Event Binding with jQuery delegate()
jQuery version 1.4.2 was released on February 19th this year and along for the ride is the new jQuery.delegate() method. This method is very similar to the $.live() method in that it is used to:
Attach a handler to the event for all elements which match the current selector, now or in the future, based upon a specific set of root elements.
So what exactly is the big deal and how is it different to $.live()? In this post I’ll look at the two side-by-side and demonstrate why $.delegate() opens up some new doors that may make you decide to let $.live() $.die().
$.delegate() – The Basics
Delegate does not replace, supercede or in any other way diminish the usefulness of $.live() – it is an alternative, allowing for each binding of event delegation to specific DOM elements. My personal view is that I prefer $.delegate() for it’s cleaner syntax and greater flexibility, but conceptually they could be likened to the $.ajax() method and $.post(): both do exactly the same thing, but one has more scope for specificity than the other. Of particular note is that the new $.delegate() method improves performance because it requires less bubbling of events.
The $.delegate() function looks like this in its most basic form:
$("table").delegate("td", "hover", function(){
$(this).toggleClass("hover");
});
This alternately assigns or removes the “hover” class to any table’s <td> element whenever the mouse hovers over that <td>. The equivalent syntax using the $.live() function looks like this:
$("table").each(function(){
$("td", this).live("hover", function(){
$(this).toggleClass("hover");
});
});
It’s still quite easy to understand what’s going on, but it is also more verbose.
The general pattern for using delegate can be thought of as:
Where to look, what to look at, when to act and how to act. So in the example above, the “where” is any table. The “what” is each table’s cell. The “when” is on a hover action and the “how” is the function defining the toggleClass() call.
The importance of context
Like many of the new changes coming out with the latest versions of jQuery, the beauty in the $.delegate() method (and the thing that differentiates it from $.live()) is that it allows you to specify a context. This means that events don’t bubble right the way up the DOM and thus your performance improves. Some believe that $.delegate() will eventually supercede $.live() for that reason.
The $.delegate() method is actually bound to a “containing element”, which not only restricts the context to a particular region of your page, but also allows for better filtering for events and makes operations like chaining a little more intuitive.
I predict that once people start to adjust to this new method, we’ll start to see $.live() begin to fall out of favour with developers and eventually be deprecated.
Hope this helps.


Thank you Phil, for being the only one to explain this to the point where it makes sense. I swear, half the time I search for help in jQuery, I get 30 pages of plugin sites. If I wanted a plugin, I would search for it.
Your where, what, when and how statement is awesome. That will help me remember how to use it no problem.
Question for you: I thought I read somewhere, that if you are using .live(), and add elements on the fly, it will not add the event handler, where as .delegate() will. Any idea if this is true?
Wow. Thanks very much for that very high praise.
To answer your question, using the live() function in most cases will add the event handler the same as bind() or delegate() will, unless you’re using version 1.3.x; in which case you can only bind:
click, dblclick, keydown, keypress, keyup, mousedown, mousemove, mouseout, mouseover, and mouseup.
No problem! I had been looking for this for a while, and jQuery’s documentation on delegate() is at the very least confusing. The comments under it make it worse. Half the people that posted there didn’t seem to understand, even while they were explaining, and then getting called down on giving bad info. I got lucky that your blog was listed when I searched, cause the first 5-6 listings were useless.
Again, thanks. I used it last night after upgrading my blog to 1.4.2 and it worked fine. Made easier by the where, what, when and how.
Just wondering, why use ‘each()’ in your ‘live()’ example? Wouldn’t $(‘table td’).live() work the same?
Honestly? It probably would. I can’t remember if there was a reason I structured it that way. If I can find time, I’ll code the two up and measure their performance.