I am curious why when I replace .live()
with .on()
my events don\'t work after inserting AJAX\'s response via html()
method. Assume I
.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
.
It is indeed a replacement for .delegate
and .live
, but you have to pass in some additional parameters:
var container = $('.a').on('click', '.alert-link', function() {
alert('abc');
return false;
}).on('click', '.ajax-update', function() {
// something that uses AJAX to update .a, like:
container.load('some-url');
return false;
});
For more information, see the documentation.
Your particular conversion to .on()
didn't work properly because you were using the static form of .on()
instead of the dynamic form of .on()
. Instead of the static form:
$('.alert-link').on("click", function(){
you need to use the dynamic form like this:
$(someStaticParentObject).on("click", '.alert-link', function(){
This will bind the event handler to someStaticParentObject
and then use delegated event handling for any child events that originate on an item that matches the selector '.alert-link'
. Your version was immediately binding to whatever '.alert-link'
items existed at the time you installed the event handler (static binding) and was not using delegated event handling to handle events from objects that aren't yet created.
See these previous answers for a good explanation of .live()
vs. .on()
and why .live()
can lead to performance issues in some cases:
Does jQuery.on() work for elements that are added after the event handler is created?
How does jQuery's new on() method compare to the live() method in performance?
What's the difference between jQuery.bind() and jQuery.on()?
jQuery .live() vs .on() method for adding a click event after loading dynamic html
Why not take Javascript event delegation to the extreme?
In a nutshell:
$(".item").live('click', fn);
is functionality equivalent to:
$(document).on('click', '.item', fn);
The two main drawbacks of .live()
are:
".item"
immediately which is purely wasted cycles because the result isn't used at all..live()
is hardwired to the document object. It uses delegated event handling to be able to handle objects that come and go, but all .live()
event handlers are assigned to the document object. If you have a lot of them, it can be a big performance bottleneck because every event that bubbles up to the document has to be evaluated against the selectors of all .live()
event handlers. .on()
on the other hand can be bound not only to the document object, but also to an ancestor that is much closer to the actual origin of the events and when there are lots of delegated event handlers, it can be a LOT more efficient to find the events closer so that only the events that are close to the object are processed through the .on()
selectors, thus improving performance. For example, the above handlers could be done like this:
$("#container").on('click', '.item', fn);
where #container
is a parent of the dynamic .item
objects.