Why does this work:
$.ajax(
{
url: "/some/url.php",
data: { s:"stuff" },
success: function(result)
{
// Result being <button id="clickme">Click me!</button>
$("#container").html(result);
// Event trigger *in* AJAX
$("#clickme").on("click", function()
{
alert("Hai");
});
}
});
And this doesn’t:
$.ajax(
{
url: "/some/url.php",
data: { s:"stuff" },
success: function(result)
{
// Result being <button id="clickme">Click me!</button>
$("#container").html(result);
}
});
// Event trigger outside AJAX, for better overview, like event grouping,
// shorter AJAX functions, etc
$("#clickme").on("click", function()
{
alert("Hai");
});
Using jQuery v1.7.2
First of all,
ondoesn’t use delegation with that signature. That means it directly attaches the event listener to the found elements.Secondly, your second code is executed before the ajax request is even made, so no elements are found at this point and the code does not attach any event listeners.
If you wanted to use delegation with
on, the signature goes like:Where
documentshould be closest static parent element – but it works withdocumentas well (that’s what.livedoes after all)documentis reliable because it’s always there. But if you have a closer static parent element that can be found at this point in the DOM, you could rather delegate to that.The reason
document,"body"etc are not recommended is because they add a processing overhead for alltypeevents on the page.Consider
$(document).on("mousemove", ".myElement", fn);Now, anytime the mouse is moved on the page, unless propagation is stopped by lower level listeners, jQuery has to process through the entire propagation path
every time to see if any element in the propagation path matched the given
.myElement-selector.If you instead added
$("#element").on("mousemove", ".myElement", fn);, this processing would only be done for mousemove events that happenin the
"#element"area on the page.