In jQuery v1.7 a new method, on was added. From the documentation:
‘The .on() method attaches event handlers to the currently se
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
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")
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.
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.
(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:
Use on
like bind
:
/* Old: */ $(".foo").bind("click", handler);
/* New: */ $(".foo").on("click", handler);
Use on
like delegate
(event delegation rooted in a given element):
/* Old: */ $("#container").delegate(".foo", "click", handler);
/* New: */ $("#container").on("click", ".foo", handler);
Use on
like live
(event delegation rooted in the document):
/* Old: */ $(".foo").live("click", handler);
/* New: */ $(document).on("click", ".foo", handler);
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().