173

In jQuery v1.7 a new method, on was added. From the documentation:

‘The .on() method attaches event handlers to the currently selected set of elements in the jQuery object. As of jQuery 1.7, the .on() method provides all functionality required for attaching event handlers.’

What's the difference with live and bind?

Alnitak
  • 334,560
  • 70
  • 407
  • 495
Diego
  • 16,436
  • 26
  • 84
  • 136
  • 5
    *related*: [What's the difference between jQuery .live() and .on()](http://stackoverflow.com/questions/8042576/whats-the-difference-between-jquery-live-and-on) – Felix Kling Nov 09 '11 at 13:32
  • Had look for something like that before asking and didn't succeed. Thanks! – Diego Nov 09 '11 at 13:33

7 Answers7

329

on() is an attempt to merge most of jQuery's event binding functions into one. This has the added bonus of tidying up the inefficiencies with live vs delegate. In future versions of jQuery, these methods will be removed and only on and one will be left.

Examples:

// Using live()
$(".mySelector").live("click", fn);

// Equivalent `on` (there isn't an exact equivalent, but with good reason)
$(document).on("click", ".mySelector", fn);
// Using bind()
$(".mySelector").bind("click", fn);

// Equivalent `on`
$(".mySelector").on("click", fn);
// Using delegate()
$(document.body).delegate(".mySelector", "click", fn);

// Equivalent `on`
$(document.body).on("click", ".mySelector", fn);

Internally, jQuery maps all these methods and shorthand event handler setters to the on() method, further indicating that you should ignore these methods from now on and just use on:

bind: function( types, data, fn ) {
    return this.on( types, null, data, fn );
},
live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
},
delegate: function( selector, types, data, fn ) {
    return this.on( types, selector, data, fn );
},

See https://github.com/jquery/jquery/blob/1.7/src/event.js#L965.

BlueRaja - Danny Pflughoeft
  • 84,206
  • 33
  • 197
  • 283
Andy E
  • 338,112
  • 86
  • 474
  • 445
  • As @JamWaffles said the most understandable answer. Would you please add the comparison between on and delegate to complete the answer? Thanks! – Diego Nov 09 '11 at 13:08
  • lols, you added the jquery source 4 seconds before me :D btw live equivalent context is document, not document.body – Esailija Nov 09 '11 at 13:10
  • 1
    You might want to refer to the 1.7 tag instead, otherwise future changes might make your link invalid (not point to the right location): https://github.com/jquery/jquery/blob/1.7/src/event.js#L965 – Felix Kling Nov 09 '11 at 13:34
  • 3
    `$(document.body).delegate("click", ".mySelector", fn);` should be `$(document.body).delegate(".mySelector", "click", fn);` – Sonny Nov 16 '11 at 14:20
  • if bind is being weeded out, what about unbind? – dsdsdsdsd Mar 31 '13 at 19:49
  • 2
    @dsdsdsdsd, *off* serves as the generic replacement for unbind, unlive and undelegate. – Andy E Mar 31 '13 at 23:17
  • Also, when you use $(this) as the selector for .on, the second argument '.mySelector' is not needed. For when you iterate with .each – TrySpace May 29 '13 at 17:19
  • so .bind is equal to .on without sending the selector parameter? I wonder why .on is preferred I always use .bind. From the top of my head I never needed that parameter. – Hoffmann Aug 19 '13 at 14:28
  • @Hoffmann: `on` is preferred because it is the consolidated function of all event-binding methods. As my answer shows, `bind` just calls `on` under the hood anyway. This indicates the possibility that `bind` may be deprecated in a future version of jQuery. – Andy E Aug 19 '13 at 14:31
12

on is in nature very close to delegate. So why not use delegate? It's because on doesn't come alone. there's off, to unbind event and one to create an event to be executed one time only. This is a new event's "package".

The main problem of live is that it attaches to "window", forcing a click event (or other event) on an element deep inside the page structure (the dom), to "bubble up" to the top of the page to find an event handler willing to deal with it. At each level, all event handlers have to be checked, this can add up fast, if you do deep imbrication (<body><div><div><div><div><table><table><tbody><tr><td><div><div><div><ul><li><button> etc etc etc...)

So, bind, like click, like other shortcut event binders attach directly to the event target. If you have a table of, let's say, 1000 lines and 100 columns, and each of the 100'000 cells includes a checkbox which click you want to handle. Attaching 100'000 event handlers will take a lot of time on page load. Creating a single event at the table level, and using event delegation is several orders of magnitude more efficient. The event target will be retrieved at event execution time. "this" will be the table, but "event.target" will be your usual "this" in a click function. Now the nice thing with on is that "this" will always be the event target, and not the container it is attached to.

TrySpace
  • 2,233
  • 8
  • 35
  • 62
roselan
  • 3,755
  • 1
  • 20
  • 20
5

with .on method it is possible to do .live, .delegate, and .bind with the same function but with .live() only .live() is possible ( delegating events to document ).

jQuery("#example").bind( "click", fn ) = jQuery( "#example").on( "click", fn );

jQuery("#example").delegate( ".examples", "click", fn ) = jQuery( "#example" ).on( "click", ".examples", fn )

jQuery("#example").live( fn ) = jQuery( document ).on( "click", "#example", fn )

I can confirm this directly from jQuery source:

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

live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
},

delegate: function( selector, types, data, fn ) {
    return this.on( types, selector, data, fn );
},

jQuery( this.context )? this.context === document in most cases

Esailija
  • 138,174
  • 23
  • 272
  • 326
3

(My opening sentence made more sense before you changed the question. Originally you'd said "What's the difference with live?")

on is more like delegate than it is like live, it's basically a unified form of bind and delegate (in fact, the team said its purpose is "...to unify all the ways of attaching events to a document...").

live is basically on (or delegate) attached to the document as a whole. It's deprecated as of v1.7 in favor of using on or delegate. Going forward, I suspect we'll see code using on solely, rather than using bind or delegate (or live)...

So in practice, you can:

  1. Use on like bind:

    /* Old: */ $(".foo").bind("click", handler);
    /* New: */ $(".foo").on("click", handler);
    
  2. Use on like delegate (event delegation rooted in a given element):

    /* Old: */ $("#container").delegate(".foo", "click", handler);
    /* New: */ $("#container").on("click", ".foo", handler);
    
  3. Use on like live (event delegation rooted in the document):

    /* Old: */ $(".foo").live("click", handler);
    /* New: */ $(document).on("click", ".foo", handler);
    
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    In the page I linked says "If new HTML is being injected into the page, select the elements and attach event handlers after the new HTML is placed into the page. Or, use delegated events to attach an event handler, as described next.". So on is more likely bind, not live. Am I right? – Diego Nov 09 '11 at 12:58
  • @Diego: `on` is a combination of `bind` and `delegate`, and as I said, not very much like `live`. You can use `on` like `bind` (attach a handler directly to an element), or you can use `on` like `delegate` (attach a handler to an element, but fire the event only if the actual element clicked matches a selector, and as though that element were the one the event happened on -- e.g., event delegation), **or** you can use it like `live` (`delegate` using the document as the root). It's the event delegation that makes it useful if you're adding elements dynamically. – T.J. Crowder Nov 09 '11 at 13:02
  • 1
    the old live could also be used like delegate: `$("#id", ".class").live(fn)` = `$(".class").delegate("#id", fn );` Actually in old jQuery source they used live as the general case and delegate as a special case, which made this all the more confusing when you think about it. – Esailija Nov 09 '11 at 13:21
  • @Esailija: Fair enough. I don't think that's the use it got known for, because they added `delegate` right quick, but still. :-) – T.J. Crowder Nov 09 '11 at 13:22
2

There isn't one for the basic use case. These two lines are functionally the same

$( '#element' ).bind( 'click', handler );
$( '#element' ).on( 'click', handler );

.on() can also do event delegation, and is preferred.

.bind() is actually just an alias for .on() now. Here's the definition of the bind function in 1.7.1

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

The idea for adding .on() was to create a unified event API, rather than having multiple functions for binding event; .on() replaces .bind(), .live() and .delegate().

Dan
  • 1,295
  • 2
  • 22
  • 46
2

live is the shortcut for .on() now

//from source http://code.jquery.com/jquery-1.7.js
live: function( types, data, fn ) {
    jQuery( this.context ).on( types, this.selector, data, fn );
    return this;
}

also this post may be usefull for you http://blog.jquery.com/2011/11/03/jquery-1-7-released/

doochik
  • 36
  • 1
  • 3
0

Something you should be aware of if you want to get the event handlers associated with the element - pay attention which element the handler was attached to!

For example, if you use:

$('.mySelector').bind('click', fn);

you will get the event handlers using:

$('.mySelector').data('events');

But if you use:

$('body').on('click', '.mySelector', fn);

you will get the event handlers using:

$('body').data('events');

(in the last case the relevant event object will have selector=".mySelector")

Alexander
  • 7,484
  • 4
  • 51
  • 65
  • `events` is undocumented anyways and I think it no longer works in 1.9 – John Dvorak Oct 15 '13 at 11:32
  • Right. One can use _data instead of data in the newer versions. The answer was about the difference in the "event owner" rather the exact syntax for old or new versions. There are other posts about the exact syntax for different JQuery versions. For example http://stackoverflow.com/questions/2518421/jquery-find-events-handlers-registered-with-an-object – Alexander Oct 16 '13 at 06:56