Why does this break in jQuery 1.7.x?
Question by qwertymk
The following code snipplet shows what my issue is:
var $div = $('<div>');
$('span').live('click', function() { this.innerHTML = 'changed'; });
$div.append(
$('<span>span</span>').click()
);
$div.appendTo('body');
This works as expected in jQuery 1.6.x but not in 1.7.x
Why is it not working in 1.7.x? Is it a bug? Is there any way to get it to work in 1.7.x?
Answer by Pointy
The way that event handling works has changed in the 1.7 release. Before the <span>
is added to the DOM, events triggered on it will not bubble up to the <body>
as they once did (erroneously, in my opinion; the 1.7 behavior makes much more sense).
The triggering of the event on the <span>
probably works, but because the event does not bubble to the <body>
the actual handler that deals with your .live()
setup cannot be called.
edit — it may be the document element to which events bubble; whatever, the point is the same.
edit again — Here’s a way to make this work so that you can trigger handlers before adding your elements to the DOM:
$('<div></div>').on('click', 'span', function() {
this.innerHTML = "Changed!";
}).append($('<span>span</span>'))
.find('span').click().end()
.appendTo($('body'));
That sets up the “click” handler as a delegated handler on the nascent <div>
directly. Then, after appending the new <span>
to that element, it’s then possible to trigger a “click” on that <span>
and have the handler be called. That happens before the whole thing is appended to the <body>
.
Answer by Starx
The working solution for both 1.6 and 1.7
var $div = $('<div>');
$('span').live('click', function() { this.innerHTML = 'changed'; });
$div.append('<span>span</span>');
$div.appendTo('body');
$('span').trigger('click');
Demo
However, omit the risk of using a deprecated function with replacing live
with on
$('span').on('click', function() { this.innerHTML = 'changed'; });