6

I am trying to register a event on elements like this:

$(document).ready(function() {
   $('.classname').change(function(){
       alert ('This line is never triggered');
   });
});

But the problem is that .classname elements are later loaded into the dom by ajax. So, how do I correctly register an event in this case? Is it possible to do it only once (I mean, not every time the new element appears?)

Dziamid
  • 11,225
  • 12
  • 69
  • 104

3 Answers3

15

You must use on() as live() is deprecated:

$(document).ready(function() {
   $( document ).on('change', '.classname', function(){
       alert ('This line is never triggered');
   });
});
Nicola Peluchetti
  • 76,206
  • 31
  • 145
  • 192
  • live looks really cool. very interesting how the jquery folks were able to make it happen: "The event bubbles up until it reaches the root of the tree, which is where .live() binds its special handlers by default." Thanks I did not know about this, I've been doing the binding after every ajax call! – mikey Jul 05 '11 at 12:36
  • `live()` is deprecated now. Use `on()`. See this answer: http://stackoverflow.com/a/8191450/1738090 – w3bshark May 15 '13 at 13:27
5

Further to the answers suggesting that you use live(), it's also possible to use delegate(), for example:

$('form').delegate('.classname', 'change', function(){
    alert("This will alert when the newly-added element registers a 'change' event.");
});

For delegate the element to assign the selector (.classname') to, in this case the $('form') must exist in the DOM at the time of assignment.


Edited to note that the following section (following the next 'edited' until the 'Reference') is wrong:

JS Fiddle demo.

Calling stopPropagation() on an element between the element selected by the delegate() selector and the target to which the event is delegate()-d does somewhat predictably (though I hadn't realised this before) prevent the delegation from occurring.

Edited in response to question, in comments, from OP:

Hey, just noticed, that if any parent's event handler calls stopPropagation, then live event would stop! Is this correct?

Not according to the jQueryAPI (the entry is linked-to below):

...events handled by .delegate() will always propagate to the element to which they are delegated...

I've not tried/verified this as yet, but it seems that even if an element that sits between the target element ($('.classname')) and the delegate()-d element ($('form')) calls stopPropagation() it shouldn't have an adverse effect on the delegate().

Reference:

David Thomas
  • 249,100
  • 51
  • 377
  • 410
  • Hey, just noticed, that if any parent's event handler calls stopPropagation, then live event would stop! Is this correct? – Dziamid Jul 05 '11 at 12:53
  • I've seen the docs, but have a look at this example: http://jsfiddle.net/WAXfc/1/. The same applies for delegate method, but it safer to use, I think. – Dziamid Jul 05 '11 at 13:26
  • @Dziamid: you're [absolutely right](http://jsfiddle.net/davidThomas/WAXfc/3/) (although your linked demo used `live()` rather than `delegate()`, so I updated the demo). – David Thomas Jul 05 '11 at 13:35
2

Use live which binds the event to all elements now and in the future:

$(document).ready(function() {
   $('.classname').live('change',function(){
       alert ('This line is never triggered');
   });
});

Fore more information, have a look at the documentation here.

Niklas
  • 29,752
  • 5
  • 50
  • 71