Jquery: Live() VS Delegate()

Jquery live() vs delegate()

I never use live; I consider the benefits of using delegate to be so substantial as to be overwhelming.

The one benefit of live is that its syntax is very close to that of bind:

$('a.myClass').live('click', function() { ... });

delegate, however, uses a slightly more verbose syntax:

$('#containerElement').delegate('a.myClass', 'click', function() { ... });

This, however, seems to me to be much more explicit about what is actually happening. You don't realise from the live example that the events are actually being captured on document; with delegate, it is clear that the event capturing happens on #containerElement. You can do the same thing with live, but the syntax becomes increasingly horrid.

Specifying a context for your events to be captured also improves performance. With the live example, every single click on the entire document has to be compared with the selector a.myClass to see if it matches. With delegate, that is only the elements within #containerElement. This will obviously improve performance.

Finally, live requires that your browser looks for a.myClass whether or not it currently exists. delegate only looks for the elements when the events are triggered, giving a further performance advantage.


NB delegate uses live behind the scenes, so you can do anything with live that you can do with delegate. My answer deals with them as they are commonly used.

Note also that neither live nor delegate is the best way to do event delegation in modern jQuery. The new syntax (as of jQuery 1.7) is with the on function. The syntax is as follows:

$('#containerElement').on('click', 'a.myClass', function() { ... });

jQuery: live() vs delegate()

.live() requires you run the selector immediately, unless you're using the result it's very wasteful. The event handler here is attached to document, so all event of that type from any elements bubbling must be checked. Here's a usage example:

$(".myClass").live("click", function() { alert("Hi"); });

Note that the statement $(".myClass") ran that selector to find all elements with that class even though we don't care about them, all we wanted was the string ".myClass" to match later when click events bubble up to document.


.delegate() actually uses .live() internally, but with a context. The selector is not run immediately, so it's more efficient already, and it doesn't attach to document (though it can) it's much more local...and all those other events from other element trees you don't care about are never even checked when bubbled...again more efficient. Here's a usage example:

$("#myTable").delegate("td", "click", function() { alert("Hi"); });

Now what happened here? We ran $("#myTable") to get the element to attach to (admittedly more expensive than document, but we're using the result. Then we attach an event handler to that (or those in other cases) elements. Only clicks from within that element are checked against the "td" selector when they happen, not from everywhere like .live() does (since everything is inside document).

Difference between jQuery `click`, `bind`, `live`, `delegate`, `trigger` and `on` functions (with an example)?

Before you read this, pull this list of events up in another page, the API itself is tremendously helpful, and all of what I'm discussing below is linked directly from this page.

First, .click(function) is literally a shortcut for .bind('click', function), they are equivalent. Use them when binding a handler directly to an element, like this:

$(document).click(function() {
alert("You clicked somewhere in the page, it bubbled to document");
});

If this element gets replaced or thrown away, this handler won't be there anymore. Also elements that weren't there when this code was run to attach the handler (e.g. the selector found it then) won't get the handler.

.live() and .delegate() are similarly related, .delegate() actually uses .live() internally, they both listen for events to bubble. This works for new and old elements, they bubble events the same way. You use these when your elements may change, e.g. adding new rows, list items, etc. If you don't have a parent/common ancestor that will stay in the page and not be replaced at any point, use .live(), like this:

$(".clickAlert").live('click', function() {
alert("A click happened");
});

If however you do have a parent element somewhere that isn't getting replaced (so its event handlers aren't going bye bye) you should handle it with .delegate(), like this:

$("#commonParent").delegate('.clickAlert', 'click', function() {
alert("A click happened, it was captured at #commonParent and this alert ran");
});

This works almost the same as .live(), but the event bubbles fewer times before being captured and the handlers executed. Another common use of both of these is say your class changes on an element, no longer matching the selector you originally used...with these methods the selector is evaluated at the time of the event, if it matches, the handler runs...so the element no longer matching the selector matters, it won't execute anymore. With .click() however, the event handler is bound right on the DOM element, the fact that it doesn't match whatever selector was used to find it is irrelevant...the event is bound and it's staying until that element is gone, or the handler is removed via .unbind().

Yet another common use for .live() and .delegate() is performance. If you're dealing with lots of elements, attaching a click handler directly to each element is expensive and time consuming. In these cases it's more economical to setup a single handler and let bubbling do the work, take a look at this question where it made a huge difference, it's a good example of the application.


Triggering - for the updated question

There are 2 main event-handler triggering functions available, they fall under the same "Event Handler Attachment" category in the API, these are .trigger() and .triggerHandler(). .trigger('eventName') has some shortcuts built-in for the common events, for example:

$().click(fn); //binds an event handler to the click event
$().click(); //fires all click event handlers for this element, in order bound

You can view a listing including these shortcuts here.

As for the difference, .trigger() triggers the event handler (but not the default action most of the time, e.g. placing the cursor at the right spot in a clicked <textarea>). It causes the event handlers to occur in the order they were bound (as the native event would), fires the native event actions, and bubbles up the DOM.

.triggerHandler() is usually for a different purpose, here you're just trying to fire the bound handler(s), it doesn't cause the native event to fire, e.g. submitting a form. It doesn't bubble up the DOM, and it's not chainable (it returns whatever the last-bound event handler for that event returns). For example if you wanted to trigger a focus event but not actually focus the object, you just want code you bound with .focus(fn) to run, this would do that, whereas .trigger() would do that as well as actually focus the element and bubble up.

Here is a real world example:

$("form").submit(); //actually calling `.trigger('submit');`

This would run any submit handlers, for example the jQuery validation plugin, then try to submit the <form>. However if you just wanted to validate, since it's hooked up via a submit event handler, but not submit the <form> afterwards, you could use .triggerHandler('submit'), like this:

$("form").triggerHandler('submit');

The plugin prevents the handler from submitting the form by bombing out if the validation check doesn't pass, but with this method we don't care what it does. Whether it aborted or not we're not trying to submit the form, we just wanted to trigger it to re-validate and do nothing else. (Disclaimer: This is a superfluous example since there's a .validate() method in the plugin, but it's a decent illustration of intent)

What's the difference between .delegate() and live()?

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

jQuery: live() and delegate()

Your mistake is that you are not correctly specifying which elements should trigger the event handler (using the selector in the first parameter of delegate) and which parent element is responsible for firing off the event (using the selector in the jQuery object which starts the chaining).

The correct way is something like

$("body").delegate("div.myDiv","click",function () { 
var Pos = $(this).offset();
$("#Container").css("left", Pos.left).css("top", Pos.top);
});

See the examples for delegate.

For jQuery 1.7 and upwards, delegate (along with all other event binding methods) has been superseded by the on method, which would be used in the exact same manner:

$('body').on('click','div.myDiv',function() {
// ...
});

jQuery: on vs live

.on combines and replaces .bind, .live, and .delegate. The syntax $('selector').on('event', callback) is the moral equivalent of bind, not live.

Add a filtering selector to your call to on:

$('container').on('click', 'child-filter', callback);

In this case,

$('.a').on("click", ".alert-link", function(){
alert('abc');
return false;
});

This was changed because it is more efficient to attach a delegate handler to a more localized container element than the old .live style of attaching the handler to the root of the DOM.

In other words, even though alert-link elements will only appear inside of a small a div, with .live, jQuery listens to every single click event on the page and compares it to the delegated selector. By being more targeted, jQuery only has to process clicks on elements within a.

jQuery Mobile delegate vs live vs bind

You would bind to a "page event" that jQuery Mobile exposes, like pageinit:

$(document).delegate('#my-page', 'pageinit', function () {
//this is like document.ready for this pseudo-page
});

Since you're using jQuery Core 1.7.1 you can use .on() which has a slightly different syntax:

$(document).on('pageinit', '#my-page', function () {
//this is like document.ready for this pseudo-page
});

All three of your methods do similar things. .live() is the same thing as using .delegate() with document as the root selection but it's been depreciated so it's a good idea to stop using it (source: http://api.jquery.com/on). Using .bind() directly on the document element is the same as using .delegate() but when you use .bind() you have to determine which pseudo-page had the event fired on it in the event handler rather than in the function call.

For example:

$(document).bind('pageshow', function () {
var id = $.mobile.activePage[0].id;
//you can use $.mobile.activePage to do work on the current page
});

In general, event delegation is used when we don't know when an element will exist in the DOM. It relies on events bubbling up the DOM until they get to the root selection (in your case it's always the document element).

Docs for .delegate(): http://api.jquery.com/delegate

For more general information about the difference between these functions, see this article (I've read it to check it for accuracy and it's right-on): http://www.elijahmanor.com/2012/02/differences-between-jquery-bind-vs-live.html

delegate() vs on() in jquery?

This is what a member of the jQuery team wrote in regard to this issue in 2013:

"We haven't deprecated .bind or .delegate, nor have we indicated we're
removing them at any point.

They're each only one line in the source so size reduction isn't much of a reason to remove them.

We deprecated .live because it has lots of confusing issues that we can't fix."

Basically, while delegate() has been superseded by on(), there are no future plans to deprecate delegate() due to the fact it takes up very little space (and doesn't cause any problems).

Using jQuery delegate() to replace live()

You'd be better delegating the event handler to $(document) rather than $(".trash') as it means you're not relying on it existing.



Related Topics



Leave a reply



Submit