The difference between .bind(), .live(), and .delegate() is not always apparent. Having a clear understanding of all the differences, though, will help us write more concise code and prevent bugs from popping up in our interactive applications.
The jQuery team have announced in v1.7 a new method for binding events called `on`. This method combines the functionality of `live`, `bind`, and `delegate` described below, allowing you to specify the binding method based the arguments passed rather than by using different function names.
First, it helps to visualize the DOM tree of an HTML document. A simple HTML page would look like this:
When we click a link, it fires the `click` event on the link element, which triggers any functions we bound to that element's click event.
$('a').bind('click', function() { alert("That tickles!") });
So a click will trigger the alert.
That `click` event then propagates up the tree, broadcasting to the parent element and then to each ancestor element that the `click` event was triggered on one of the descendent elements.
In the context of manipulating the DOM, `document` is the root node.
Now we can more easily illustrate the difference between `.bind()`, `.live()`, and `.delegate()`.
$('a').bind('click', function() { alert("That tickles!") });
This is the most straight forward binding method. jQuery scans the document for all `$('a')` elements and binds the alert function to each of their `click` events.
$('a').live('click', function() { alert("That tickles!") });
jQuery binds the alert function to the `$(document)` element, along with `'click'` and `'a'` as parameters. Any time an event bubbles up to the document node, it checks to see if the event was a click and if the target element of that event matches the `'a'` CSS selector. If both are true, the function executes.
The live method can also be bound to a specific element (or "context") other than `document`, like this:
$('a', $('#container')[0]).live(...);
$('#container').delegate('a', 'click', function() { alert("That tickles!") });
jQuery scans the document for `$('#container')`, and binds the alert function along with the `click` event and `'a'` CSS selector as parameters. Any time an event bubbles up to `$('#container')`, it checks to see if the event was a click and if the target element of that event matches the CSS selector. If both checks are true, it executes the function.
Notice this is similar to `.live()`, except that it binds the handler to the specified element instead of the document root. The astute JS'er might conclude that `$('a').live() == $(document).delegate('a')`, right? Well, no, not exactly.
jQuery's delegate method is generally preferred to the live method for a few reasons. Consider the following examples:
$('a').live('click', function() { blah() });
// or
$(document).delegate('a', 'click', function() { blah() });
The latter is actually faster than the former, because the former first scans the entire document for all `$('a')` elements, storing them as jQuery objects. Even though the live function only needs to pass 'a' through as string argument to be evaluated later, the `$()` function doesn't "know" that the chained method is going to be `.live()`.
The delegate method on the other hand, only needs to find and store the `$(document)` element.
One hack to get around this is to call the live binding outside of the `$(document).ready()` state, so that it runs immediately. That way it will run before the DOM gets populated, and thus won't find the elements or create the jQuery objects.
The live function is also convoluted. Think about it; it's chained to the `$('a')` object set, but it's actually acting on the `$(document)` object. For this reason, it can get hairy trying to chain methods to it. In fact, I'd argue the live method would make more sense as a global jQuery method in the form of `$.live('a',...)`.
And finally, the live method has a very large shortcoming, and that is that it can only operate on a direct CSS selector string. This makes it very inflexible.
For more on the CSS selector shortcoming, see Exploring jQuery .live() and .die().
Update: Thanks to pedalpete on Hacker News and Ellsass below in the comments for reminding me to add this next section.
After all, `bind` seems so much clearer and more direct, doesn't it? Well, there are 2 reasons we prefer `delegate` or `live` to `bind`:
I'd like to mention one last note concerning event propagation. Typically, we can stop other handler functions from running by using event methods like:
$('a').bind('click', function(e) {
e.preventDefault();
// or
e.stopPropagation();
});
However, when we use the live or delegate methods, the handler function won't actually run until the event bubbles to the element to which the handler is actually bound. By this time, our other handler functions from `.bind()` have already run.
Comments are loading...