Is there any way to delegate an event using jQuery that will correspond to all elements on the page that match the selector, other than delegating from $(document)
?
Since that's probably poorly worded, here's the rub:
There used to be jQuery.live
that delegated events to all elements that matched the selector. This was superseded by jQuery.delegate
which delegated events within a specific context selector to its children, which in turn was superseded by jQuery.on
, which does effectively the same thing, but with different bits behind the scenes (I'd imagine).
What I want to do, is safely add an event handler to every div.foo
on my page, regardless of where it might live, or when it might live. According to the documentation, and empirical research, the following will only bind to .foo
elements that exist when the script is run. Since there is code that might place a .foo
element on the page later, this doesn't exactly work.
jQuery('.foo').on('click', handler);
Since live
is deprecated (possibly removed?), I'm trying to not use that, but the only solution I can come up with is
jQuery(document).on('click', '.foo', handler);
But isn't this what live
did originally, behind the scenes? More to the point, are there any significant reasons not to do this?
We're specifically using version 1.7.2, but generic jQuery answers would help too.
The events bubble from their source, to whatever they're delegated, so you should use jquery().on at what ever level is the lowest common parent. If that's document, then so be it.
Otherwise, if your
.foo
items are always created within a.foocontainer
(or something) then you can use that in your selector, even if there is more than one of them - you just end up attaching.I think the issue with delegating back to document is that it potentially requires the event to bubble a large number of times, incurring extra overhead in the process, so best to delegate the event as close to the source as possible.
You are correct in that binding to the document (as below) is exactly what
live()
does:The reason this is bad is because it is not very performant. Every time you click, anywhere, the
document
checks to see if it was on the delegated element.The better method is to use an element in place of
document
which is the closest parent to those which are being dynamically appended, but which is available on page load. Even if this is a top-level container, it would still offer a performance benefit over attaching everything todocument
.