views:

43

answers:

3

Since

$("table").delegate("td", "hover", function(){
    $(this).toggleClass("hover");
});

Is equivalent to the following code written using .live():

$("table").each(function(){
    $("td", this).live("hover", function(){
        $(this).toggleClass("hover");
    });
});

according to jQuery API.

I bet I'm wrong but isn't it the same of writing

$("table td").live('hover', function() {});

So, what's is .delegate() for?

+1  A: 

.live() listens on document where as .delegate() listens on a more local element, the <table> in that case.

They both act the same listening for the events to bubble, the one to .delegate() just bubbles less before being caught.

Your example of:

$("table td").live('hover', function() {});

Isn't the same, as it again attaches an event handler to document and not the <table>, so .delegate() is for more local elements, more efficient in most respects...though it still uses .live() under the covers.


Also keep in mind that $(selector) retrieves the elements, so $("table td") selects a bunch of elements really for no good reason when using .live(), where as $("table").delegate() selects only the <table> elements, so even initially it's more efficient by not running the selector and discarding the result.

Nick Craver
Is it possible to see the event listener at the Chrome Developer Tools when selecting the corresponding element?
Rodrigo Alves
Although `$("table td").live('hover', function() {});` is the same when using the `.each()` method, isn't it?
Rodrigo Alves
On the element you attach `.delegate()` to yes, you can see it in it's `.data("events")` object, or `$.cache[element[$.expando]].events`, where `elemenet[$.expando]` is the `jquery230420498204824=132` you see on the element, that 132 is the key in `$.cache`, so `$.cache[132].events` is the object you're after.
Nick Craver
@Rodrigo - Nope, it's attaching a new handler up on `document` for each loop.
Nick Craver
but `$("table td").live('hover', function() {});` attaches a new handler for every selected element, doesn't it?
Rodrigo Alves
@Rodrigo - Nope, it attaches a single handler to `document` that listens for the `.selector` ("table td")` on the jquery object that was used to call `.live()`...that's the inefficient part it really didn't need to select those elements at all.
Nick Craver
A: 

The doc :

Since the .live() method handles events once they have propagated to the top of the document, it is not possible to stop propagation of live events. Similarly, events handled by .delegate() will always propagate to the element to which they are delegated; event handlers on any elements below it will already have been executed by the time the delegated event handler is called.

MatTheCat
+5  A: 

The way live() works is that it places a handler on the top level of the DOM (the document) that detects when your chosen event bubbles up to that level (and then checks to see if it was thrown by an element that matches your selector).

delegate() works the same way, but the handler is placed on your selected element (so it can only detect events thrown by descendants of that element).

The downsides of live() are 1) the performance issues inherent in detecting and checking all events that bubble to the document level, and 2) the fact that you can't stop propagation at all on those events (since you won't know about them until they reach the document level).

delegate() mitigates both of those issues by letting you constrain the handler to a smaller set of elements (the elements that match your selector and their descendants) rather then the whole page.

JacobM