Efficiency of adding a listener to a jQuery class set, compared to using $.each

javascript, jquery, jquery-plugins, optimization

Solution

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.`

Problem

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 comes 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 comes 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; } ```

Original source

Related problems