☕ 5 min read
Before jQuery 1.7 we used to distinguish $.fn.bind
from $.fn.live
and $.fn.delegate
to create events listeners.
$.fn.bind
is the most basic one which attach an event listener to an object, usually a DOM node.
$.fn.live
is more powerful as it attach the event listener at the document root and makes the behavior live in every corresponding element of the DOM, even if they are created later.
$.fn.delegate
behaves almost the same as $.fn.live
, but you specify a DOM node where to attach your live listener, which is much more faster.
$.fn.delegate
is more efficient than $.fn.live
which is more efficient than $.fn.bind
.
Since jQuery 1.7, all of these methods have been replaced by the $.fn.on
method. Performance principles still the same, but the syntax changes.
bind
you upThe most basic method to attach an event listener to a jQuery object. It’s commonly used on DOM elements to create some interaction with the user:
// Basic use of $.fn.bind
$('div#main-content').bind('click', function() { … });
Your object is now listening at the event named 'click'
and will do something everytime this event is triggered. With the previous code, for instance, the functon defined will be triggered everytime you click on the #main-content
element.
'click'
is one of the usual events name which has a shorthand method which is equivalent:
// Equivalent of the previous code
$('div#main-content').click(function() { … });
However, you can pass any event name you may have specify within your code. In fact, this is the key start for event-driven programming in JS, which helps to create advanced web-applications.
$('#foo').bind('my-event', function() { … });
$('#foo').trigger('my-event'); // Will trigger the binded event
The method to stop such an event listener is $.fn.unbind
.
Until jQuery 1.7, this was the most basic way to do things.
live
Although $.fn.bind
principle is very nice, the method is very limited. It basically has two downsides:
It attaches an event listener for every single element which matches the selector, which is not the most efficient solution when you target more than one element
It attaches an event listener only for elements which matches the selector at this time, if you modify the DOM and want to create the same elements, you’ll need to bind events again.
// This sucks…
$('a.tooltip').bind('click', function() { … });
// or $('a.tooltip').click(function() { … });
The solution found before jQuery 1.7 was the $.fn.live
method:
// Basic use of $.fn.live
$('li.text-info').live('hover', function() { … });
Instead of attaching an event listener to every single element, it attaches just one at the document root level. Doing so, any new element which matches the selector will behave the same. Futhermore, it’s much more efficient if you speak about performance.
The method to stop such an event listener is $.fn.die
.
The method is deprecated since jQuery 1.7, but the principle still the same, which is good to keep in mind.
delegate
The $.fn.delegate
method is basically the same than the $.fn.live
, coming with the same advantages over $.fn.bind
:
// Basic use of $.fn.delegate
$('ul#main-navigation').delegate('li.text-info', 'hover', function() { … });
The point is that, instead of attaching every event listener to the document root, you specify a DOM element where you want to focus. Doing so increase significantly performance as it’s much more specific!
The method to stop such an event listener is $.fn.undelegate
.
on
Since jQuery 1.7, all of the previous methods have been merged into one single, powerful method: $.fn.on
.
Now you’ve understood the previous ones, let see what are the equivalent syntaxes with the single new method:
// Basic use of $.fn.on instead of $.fn.bind
$('div#main-content').on('click', function() { … });
// Basic use of $.fn.on instead of $.fn.live
$(document).on('hover', 'li.text-info', function() { … });
// Basic use of $.fn.on instead of $.fn.delegate
$('ul#main-nav').on('hover', 'li.text-info', function() { … });
The distinction between $.fn.live
and $.fn.delegate
is more clear with that single method, and the emphasis on a powerful delegation makes sense (excepted if you explicitly want to attach your listener to the root of the document, which is rare).
You can either pass event data through the method:
// Give some data to the event
$('a').each(function(i) {
$(this).on('click', { index: i }, function(e) {
alert('My index is ' + e.data.index)
})
})
The use of $.fn.on
is pretty straightforward which makes event handling dead easy with jQuery!
The method to stop such an event listener is… $.fn.off
.
As explained, here are the list of methods from the most efficient to the less one:
.on(events, selector, [data,] handler)
equivalent to $.fn.delegate
$(document).on(events, selector, [data,] handler)
equivalent to $.fn.live
.on(events, [data,] handler)
equivalent to $.fn.bind
In a nutshell:
.on(events, selector, [data,] handler)
$(document).on(events, selector, [data,] handler)
.on(events, [data,] handler)
, or the shorthand function if existsThis was a short and friendly reminder about event delegation in jQuery.
No hot news but such a big deal in this article. That was a point worth noting you could also find easily, doing some researches through the Internet.
I realized very few time ago that I always used shorthand functions, dealing with a bunch of DOM elements sometimes, when I could have used more efficient methods. When you’ve to deal with more than one element, think about the $.fn.on
method!
I hope this have you learn something or refresh your mind on that point. If so, don’t hesitate to leave me comment below ;-)
Plop!