admin管理员组

文章数量:1327849

Initial instincts tell me that adding a listener, either using bind or a straightforward event method to a jQuery set of elements, such as..

$('.className').click(funcName);

Is much more appropriate than using a $.each method to add a listener one by one to the same set, as...

$('.className').each(function(){ $(this).click(funcName); });

But when it es to plugin development, and you are dealing with the possibility of users calling an instance of your plugin multiple times throughout the lifetime of a page, on page load and through ajax long after page load, is it wrong to apply handlers to each element itself, rather than trying to abstract the handlers to their global class set?

My main question I'm dealing with is "What is the best way to deal with multiple instances of a plugin being called when it es to event handling? As to reduce the workload?" I know we can bind and unbind, but is there a better way?

EDIT

partial code from plugin construct

init : function(){

  this.each(function(opts){

  // adding event handlers here removes
  // the need to worry about multiple instances
  // and duplicate handles over the lifetime of the page

  });

  // adding 'global' handlers here may/may not be more
  // efficient, but adds an issue of multiple instances

  return this;

}

Initial instincts tell me that adding a listener, either using bind or a straightforward event method to a jQuery set of elements, such as..

$('.className').click(funcName);

Is much more appropriate than using a $.each method to add a listener one by one to the same set, as...

$('.className').each(function(){ $(this).click(funcName); });

But when it es to plugin development, and you are dealing with the possibility of users calling an instance of your plugin multiple times throughout the lifetime of a page, on page load and through ajax long after page load, is it wrong to apply handlers to each element itself, rather than trying to abstract the handlers to their global class set?

My main question I'm dealing with is "What is the best way to deal with multiple instances of a plugin being called when it es to event handling? As to reduce the workload?" I know we can bind and unbind, but is there a better way?

EDIT

partial code from plugin construct

init : function(){

  this.each(function(opts){

  // adding event handlers here removes
  // the need to worry about multiple instances
  // and duplicate handles over the lifetime of the page

  });

  // adding 'global' handlers here may/may not be more
  // efficient, but adds an issue of multiple instances

  return this;

}
Share Improve this question edited May 9, 2012 at 17:48 anson asked May 9, 2012 at 15:44 ansonanson 4,1642 gold badges24 silver badges30 bronze badges 4
  • $('.className').click will probably use .each() internally at some stage. – Felix Kling Commented May 9, 2012 at 15:45
  • I've wondered this actually... – anson Commented May 9, 2012 at 15:45
  • 2 See: github./jquery/jquery/blob/1.7.2/src/event.js#L936 (.click calls .on). – Felix Kling Commented May 9, 2012 at 15:48
  • 1 It all boils down to addEventListener or attachEvents at some stage which is a 1-1 binding b/w element and the handler, so $('.className') will be iterated internally at some point to bind respective handler. – Selvakumar Arumugam Commented May 9, 2012 at 15:49
Add a ment  | 

4 Answers 4

Reset to default 4

If you call click once, jQuery will loop through the whole collection and bind the events individually. However, it will do it more efficiently than your alternative, because it does not build a new jQuery object for each element in the set, which will be very slow.

Here is the code from the jQuery source (it's the on method):

return this.each( function() {
    jQuery.event.add( this, types, fn, data, selector );
});

(event.js, line 936-8)

jQuery.event.add, which is the method that does the heavy lifting, does not need a jQuery object; the plain DOM object is what it needs. This loop (which effectively does the same thing as yours) is much superior in terms of efficiency, because the big bottleneck in your code is $(this) being called every time.

Note that the most efficient technique would be using event delegation with the same on method. This might look like this:

$(document.body).on('click', '.className', funcName);

This means "for every click inside document.body, check to see if it originated on an element matching the selector .className, and if so run funcName". You could replace document.body with any other element that contains all the potential .className elements.`

Your question is about "efficiency," which I assumes means "speed on the client". Probably any reasonable approach will have minimal impact on perceived performance, so I remend you pick the coding pattern that is easiest to maintain.

$('.className').click(funcName);

less load as it uses a single jquery object

$('.className').each(function(){ $(this).click(funcName); });

more load as it uses the initial instance, and also generates a new instance for each 'eached' element via $(this). If $('.className') contains 50 elements, you now have 51 jQuery objects, versus a single object.

As far as pluggin development, you can use javascript objects and use new for each instance of the plugin. Or you can define a parent object class, and use .each on that to set up instances. I hope this helps, it hard to make a remendation without knowing what your are cooking.

The only real way to know is to profile it. However, I'd wager that this is an exercise in premature optimization.

Calling $(this) in a loop has a negligible runtime performance hit.

If it's easier and cleaner to attach your handlers in an each loop, do it.

本文标签: