jQuery on() method on multiple selectors
Asked Answered
S

3

61

Since version 1.7 live is deprecated.

Following example is easy to make compatible with new on method:

$('nav li, #sb-nav li, #help li').live('click', function () {
    // code...
});

Using on:

$('nav, #sb-nav, #help').on('click', 'li', function () {
    // code...
});

How to rewrite following example using on?

 $('#header .fixed-feedback-bn, #sb-sec .feedback-bn').live('click', function () {
     // code...
 });
Sylviasylviculture answered 11/12, 2011 at 4:47 Comment(0)
A
112
$(document).on('click', '#header .fixed-feedback-bn, #sb-sec .feedback-bn', function () {
     // code...
 });

.live() is just binding document as listener.

My two cents are that you can almost always find a better listener than document. At bare minimum, almost all pages use a main content wrapper. This eliminates nodes in the header, footer, and sometimes sidebars as listeners.

The best way to use .on as a delegating function is to identify the nearest common ancestor that is expected to never be destroyed or otherwise have events unbound. For example, if you have a form that gets updated and changed by ajax requests, the listener could be the form node itself (if only the contents of the form are updated) or a container element (generally a div) that surrounds the form. If such a div isn't there, you could always add it in, or you could just go up the tree to the next ancestor.

[edited to add:]

In the particular sample code provided, it's hard to say if there's a better listener that would contain both #header and also #sb-sec. But imagining that these things share an ancestor with the id "mainContainer", your more efficient code simply swaps out the listener:

$('#mainContainer').on('click', '#header .fixed-feedback-bn, #sb-sec .feedback-bn', function () {
   // code...
});
Arsenical answered 11/12, 2011 at 4:54 Comment(0)
D
9

If you're trying to use .on() so that you can listen to events on DOM object that may be created after you make the initial .on() call, then the most efficient way to do so is to find an existing parent object that won't come and go and you can bind event listeners to now.

.live() put all listeners on the document object (the master parent) and could get pretty inefficient if you had a lot of listeners.

.on() allows you to specify what that parent object will most efficiently be. So, if you want to put all these event handlers in one statement and these '#header .fixed-feedback-bn, #sb-sec .feedback-bn' don't have a common parent, then you'd have to specify document as that parent like Greg has written.

But, a more efficient way of doing this would be to break this apart according to need. For the elements that have no dynamic need, just bind directly to that element. For example if #header and #sb-sec doesn't come/go and doesn't need dynamic behavior, you can just find directly to it like this:

$('#header, #sb-sec').on('click', function() {
    // code here
});

And, for elements that you need some dynamic behavior, pick an appropriate common parent and hook onto that like this using the common parent as the catch point for the events and the selector as the filter for which sub-elements you want the event to fire for:

$('#feedback').on('click', '.feedback-bn, .fixed-feedback-bn', function() {
    // code here
});
Dufresne answered 11/12, 2011 at 5:7 Comment(3)
Agreed; if you don't need to worry about elements that are being destroyed, binding a self-listener with .on() or .click() is the most efficient. I made an assumption that if they needed live() it was because they didn't want to lose their listeners, but perhaps that was not a correct assumption.Arsenical
I was guessing that something like #header wasn't dynamically coming and going and didn't need dynamic behavior, but something in the list probably does because they were considering .live() rather than .click(). In any case, I just tried to describe how you would decide how to select the different ways of using .on().Dufresne
Shouldn't it be $('#header, #sb-sec') in the code example? I.e. with a comma.Treasurehouse
P
-3

You may want to have a look at the documentation of live(), the switch to on() is documented: http://api.jquery.com/live/

Peta answered 11/12, 2011 at 5:46 Comment(1)
The documention is very incomplete on most (newer) things.Athalie

© 2022 - 2024 — McMap. All rights reserved.