178

I need to add a handler for the click event of future <div> elements, that don't exist yet. Normally, I would use jQuery's .live function to handle this, but it seems that it is now deprecated in favor of .on.

To use the .on method in this manner, jQuery suggests setting the selector parameter, to allow creating a delegated event, and offers this example code:

$("#dataTable tbody").on("click", "tr", function(event){
    alert($(this).text());
});

That's all fine and good, but what do I put in for my intial selector, where they have #dataTable tbody? Note that $.on() doesn't work.

Brad
  • 159,648
  • 54
  • 349
  • 530

2 Answers2

300

jQuery's documentation shows you would replace

$(selector).live(event, handler) 

with

$(document).on(event, selector, handler)

Also you have the option to be more precise and replace $(document) with a selector for a static parent of the element. For example, if you have a static table element and tr elements are added dynamically to the DOM, you could do something like $('table#id').on('click', 'tr', ...)

http://api.jquery.com/live/

Fabian Lauer
  • 8,891
  • 4
  • 26
  • 35
wrschneider
  • 17,913
  • 16
  • 96
  • 176
  • 1
    Thanks! I was looking all over the documentation for the `.on` function... didn't think to look at `.live`. – Brad Nov 19 '11 at 04:06
  • 7
    $(document).on("click", "a.offsite", function () { alert("Goodbye!"); }); – jhanifen Nov 12 '12 at 22:54
  • Can we use .find in the selector? – techie_28 Dec 18 '12 at 08:51
  • 4
    May I jump in here and mention that it's important you use an .on overload with a selector (as in this answer), or else you won't get the desired behavior (we want a delegated event, see http://api.jquery.com/on/) – Johannes Rudolph Jun 14 '13 at 13:04
38

I just figured it out as soon as I posted this question... Sorry about that!

The initial selector can be any parent element. Since my elements will be direct children of the body, I can use body for the selector:

$('body').on('click', '.my_class', function(event) { ...

This works because the events are going to bubble up. This is essentially normal bubbling with an extra filter of .my_class.

Brad
  • 159,648
  • 54
  • 349
  • 530
  • 9
    You should probably select the parent that is closest to the clicks, but still contains all the elements you want covered by the handler. In this case, I'd say you should select `"#dataTable`. – jfriend00 Nov 19 '11 at 01:08
  • @jfriend00, Agreed. In my actual case, the elements I'm trying to catch clicks on are children of the body, but in the future, I'll get as close to them as I can. Thanks for the advice! – Brad Nov 19 '11 at 01:12
  • 3
    Why was this downvoted? If you're going to downvote something, explain yourself so folks can learn. Otherwise you are wasting your time. – Brad Aug 21 '12 at 02:34
  • I think it was downvoted because "body" is a poor selector. The "document" selector is faster in most browsers, and you don't even have to wait for the DOM to be ready to attach stuff to it. But yeah, anyway, it's better to go as deep in the DOM as possible. – Willy Oct 15 '12 at 11:19
  • @Willy, My comment says that I was looking for elements that are children of the body... – Brad Dec 07 '12 at 20:42
  • For some reason using 'body' as the selector is giving us problems on iPad. We are now looking for something that works – Jair Reina Feb 22 '16 at 18:27
  • @JairReina I'm sure `$('body')` itself works fine on your iPad, in any browser. There's probably an issue with your events not firing the way you expect, or with your sub-selector. In any case, you should be using whatever the closest parent element is that you can. `body` is only appropriate for elements that are children of the `body`. – Brad Feb 22 '16 at 19:06