Difference Between Jquery 'Click', 'Bind', 'Live', 'Delegate', 'Trigger' and 'On' Functions (With an Example)

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)

Exact difference between bind and click in jQuery?

Bind is the general purpose, lower level function. Click is a shortcut method and is a higher level implementation of Bind. Also bind is more or less deprecated you should be using the "on" binding. i.e.

$('selector'.on("click", function () {

});

Th reason to use the "on" binding is that you ave the option of leveraging event delegation. in that you can also do this

$('ul'.on("click", "li", function () {
//do something whenever one of the list items is clicked
});

one reason for doing this is that you dont have to bind an event to each list item element. Instead you can attach one event to the parent. Suppose you had 200 list items if you used click

$('li'.on("click", function () {
//thing to do on click
});

each element would have its own listener and that would be inefficient.
but by targeting the ul wrapper parent and listening for the event to bubble up you only have to attach to one element. That is more efficient. Look up event propagation or event bubbling on the internet. A simple explanation is that when an event occurs in the DOM that event is propagated to the parents. So if you click a li the ul will also receive the event as will any other divs that wrap the ul and the body and all the way to the window.

What's the difference between .click(... and .bind('click...(in plain English)?

$().click(fn) and $().bind('click', fn) are identical at first sight, but the $.bind version is more powerful for 2 reasons:

  • $().bind() allows you to assign one handler to multiple events, e.g. $().bind('click keyup', fn).
  • $().bind() supports namespaced events - a powerful feature if you want to remove $().unbind) only certain event handlers that an element is bound to.

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

jquery use of bind vs on click

From the documentation of bind and click :

bind :

As of jQuery 1.7, the .on() method is the preferred method for
attaching event handlers to a document.

The source makes it clear there's no reason to use bind, as this function only calls the more flexible on function without even being shorter :

bind: function( types, data, fn ) {
return this.on( types, null, data, fn );
},

So I'd suggest, just like the jQuery team, to forget the old bind function, which is now useless. It's only for compatibility with older code that it's still here.

click :

This method is a shortcut for .on('click', handler)

This shortcut is of course less powerful and flexible than the on function and doesn't allow delegation but it lets you write a shorter and, arguably, slightly more readable, code when it applies. Opinions diverge on that point : some developers argue that it should be avoided as it is just a shortcut, and there's also the fact that you need to replace it with on as soon as you use delegation, so why not directly use on to be more consistent ?

What's the difference between jQuery .live() and .on()

It's pretty clear in the docs why you wouldn't want to use live. Also as mentioned by Felix, .on is a more streamline way of attaching events.

Use of the .live() method is no longer recommended since later
versions of jQuery offer better methods that do not have its
drawbacks. In particular, the following issues arise with the use of
.live():

  • jQuery attempts to retrieve the elements specified by the selector before calling the .live() method, which may be
    time-consuming on large documents.
  • Chaining methods is not supported. For example, $("a").find(".offsite, .external").live( ... ); is
    not valid and does not work as expected.
  • Since all .live() events are attached at the document element, events take the longest and slowest
    possible path before they are handled.
  • Calling event.stopPropagation()
    in the event handler is ineffective in stopping event handlers
    attached lower in the document; the event has already propagated to
    document.
  • The .live() method interacts with other event methods in ways that can be surprising, e.g.,
    $(document).unbind("click") removes all click handlers
    attached by any call to .live()!

How does jQuery's new on() method compare to the live() method in performance?

As I understand .live() and .on(), the two examples you have included do not so the same thing.

Your first one:

$('#some-button').on('click', function() {
//do something when #some-button is clicked
});

does not have a live behavior. It finds the #some-button object and installs an event handler on it directly. This is very efficient, but does not have .live() behavior. If the #some-button object does not exist at this time, no event handler will be installed ever. It is basically the same as this:

$('#some-button').click(function() {
//do something when #some-button is clicked
});

Your second one:

$('#some-button').live('click', function() {
//do something when #some-button is clicked
});

has live behavior. It installs an event handler on the document and waits for clicks targeted to an object that matches "#some-button" to bubble up to the document object. Your second one is theoretically equivalent to this:

$(document).on('click', '#some-button', function() {
//do something when #some-button is clicked
});

I say theoretically equivalent because it should install the same event handlers, but I don't know if the jQuery code for processing the two is identical or not.

One of the reasons that .live() has been deprecated is that it can be a bad thing to have a lot of .live() handlers because you get a lot of event handlers on the document object. Then, every click or even mousemove that bubbles up to the document object has to be checked against a LOT of selectors which can really slow things down.

Another issue with .live() is that it evaluates the selector "#some-button" at the time you make the call, but doesn't actually use that result so it's wasteful. The .on() version doesn't evaluate the selector passed as an argument to .on() when you make the first call because it isn't needed at that time - it's only need later when an actual click comes in that has to be compared to the selector.

With the advent of .on() (or something you could previously do with .delegate()), you can target your "live" event handlers more efficiently by not putting them all on the document object, but rather putting them on a parent object that does not come and go and is a lot closer to where the real objects are such as this:

$('#some-button-parent').on('click', '#some-button', function() {
//do something when #some-button is clicked ///////
});

This spreads the event handlers out to different objects and gets them closer to the actual objects for which they are meant meaning you don't end up with this giant list of event handlers that have to be checked against selectors on every mousemove or click event. That's why .live() has been replaced and deprecated. It's much better to use .delegate() or .on() and specify a parent object that isn't as far away as the document object.

The advantage of the new .on() syntax is that you can do both "live" and "static" event handlers with the same method now, just by varying how you pass the arguments. The jQuery object is where the event handler will be installed and the optional selector in the second argument is a selector that the event target must match. If you pass that selector, then all events hitting the object(s) specified in the jQuery object will have their target checked against that selector. If there is no selector, then only objects who's target is the same as the object specified in the jQuery object will be matched.

So, this is all the theory about how they work and why one configuration is supposed to be better than another. If you want to test real world performance, you'd have to devise some sort of performance test on event handler propagation and distribution probably in a scenario where you had a lot of "live" event handlers. That test is probably not easy to do because it may be hard to get timing info on the start/end of an event handler. You can't easily use a tool like jsperf for something like this.

jQuery: the difference between live and on for a function

From the docs:

.live( events, data, handler(eventObject) )

So the following code will simply register a live click event for #threeButtons which will receive an additional argument .markAsSpam:

$('#threeButtons').live('click', '.markAsSpam', function() {
// do some stuff
});

When using .on() however, you create a delegate where the click handler is bound on #threeButtons but the event will only fire if the clicked element matches the .markAsSpam selector.

What are the significant differences among $(sel).bind(click, $(sel).click(, $(sel).live(click, $(sel).on(click?

bind() was added in 1.0, live() in 1.3, delegate() in 1.4.2 and on() in 1.7.

As of 1.7 on() is the preferred use and live() is deprecated and not recommended at all.
If you are using 1.3 use bind() instead of live() and as of 1.4.2 use delegate() instead of live() and as of 1.7 use on() instead of any of the others.

Regarding $("selector").click. Taken from the click() documentation:

In the first two variations, this method is a shortcut for
.bind("click", handler), as well as for .on("click", handler) as of
jQuery 1.7. In the third variation, when .click() is called without
arguments, it is a shortcut for .trigger("click").

Why use on() instead of the others?
on() is the latest addition, joining the jQuery library in version 1.7. on() has several method signatures enabling it to deliver the same results previous version do but improved and optimised. To quote from the documentation:

As of jQuery 1.7, the .on() method provides all functionality required
for attaching event handlers.

There is bascialy no need to use bind() or delegate() anymore. Sure it will work and there should be no harm in using those methods but I would always assume that the latest additions are optimised and improved on any of the drawbacks of previous versions (unless otherwise stated by the documentation as it is in the case of live()).

Based on that I would recommend to use on() instead.

The reason live() is not recommended full-stop is more to do with it's drawbacks. To quote from the live() documentation.

Use of the .live() method is no longer recommended since later
versions of jQuery offer better methods that do not have its
drawbacks. In particular, the following issues arise with the use of
.live():

  • jQuery attempts to retrieve the elements specified by the selector
    before calling the .live() method, which may be time-consuming on
    large documents.
  • Chaining methods is not supported. For example, $("a").find(".offsite, .external").live( ... ); is not valid and does
    not work as expected.
  • Since all .live() events are attached at the document element, events
    take the longest and slowest possible path before they are handled.
  • On mobile iOS (iPhone, iPad and iPod Touch) the click event does not
    bubble to the document body for most elements and cannot be used with
    .live() without applying one of the following workarounds:
    1. Use natively clickable elements such as a or button, as both of these
      do bubble to document.
    2. Use .on() or .delegate() attached to an element below the level of document.body,
      since mobile iOS does bubble within the body.
    3. Apply the CSS style cursor:pointer to the element that needs to bubble
      clicks (or a parent including document.documentElement). Note however,
      this will disable copy\paste on the element and cause it to be
      highlighted when touched.
  • Calling event.stopPropagation() in the event handler is ineffective in
    stopping event handlers attached lower in the document; the event has
    already propagated to document.
  • The .live() method interacts with other event methods in ways that can
    be surprising, e.g., $(document).unbind("click") removes all click
    handlers attached by any call to .live()!

There is a lot more goodies in the documentation though.

Additional Resources
click()
bind()
live() (don't use)
delegate()
on()

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.



Related Topics



Leave a reply



Submit