labroo
labroo

Reputation: 2961

"on" not binding to dynamically added elements

My HTML

<div>    
    <span  class="more-available" data-completeMessage="This is the complete message you see after clicking more">Hello</span>​
</div>

I add a anchor tag to the end dynamically and then want to attach a click handler to the anchor tag. So I do this

$(document).ready(function() {

   //Attach future proof click event to an anchor tag
   $('a.more').on('click', function() {
      var $parent = $(this).parent();
      $parent.text($parent.data('completemessage'));
   });

   //Add the anchor tag
   $('span.more-available').append($('<a class="more">...more</a>'));
});;​

This does not work. If i replace "on" by "live" it works. (but live is depreciated)

I know I can do this

$(document).ready(function() {

    $('div').on('click','a.more', function() {
        var $parent = $(this).parent();
        $parent.text($parent.data('completemessage'));
    });

    $('span.more-available').append($('<a class="more">...more</a>'));
});;​

and it works, but my question is...

Was I wrong in assuming that "on" provides all the functionality of live? Does "on" not bind to future elements? Is this correct behavior, or am I doing something wrong.

fiddle: http://jsfiddle.net/arishlabroo/pRBke/5/

Upvotes: 6

Views: 2017

Answers (3)

Selvakumar Arumugam
Selvakumar Arumugam

Reputation: 79850

Use it like below,

$('span.more-available').on('click', 'a.more', function () {
   //..your code
});

You cannot just replace replace .live with .on instead you need to bind the handler to the parent element with the specific selector meaning the handle will be delegated when the event is triggered for the matching selector. In above, the you are adding a listener to span.more-available which will execute the handler only when the matching selector a.more is triggered.

In short follow the two steps to replace .live with .on,

  1. Find the closest parent elements to which the element will be added dynamically.
  2. Bind the handler to parent element with the dynamic elements selector as the 2nd argument.

Upvotes: 2

Sampson
Sampson

Reputation: 268492

According to the jQuery documentation for the $.live() method:

As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live().

The documentation for $.live() further goes on to show us the methods and syntax to use for the successors of this method:

Rewriting the .live() method in terms of its successors is straightforward; these are templates for equivalent calls for all three event attachment methods:

$(selector).live(events, data, handler);                // jQuery 1.3+
$(document).delegate(selector, events, data, handler);  // jQuery 1.4.3+
$(document).on(events, selector, data, handler);        // jQuery 1.7+

If you're using jQuery 1.7 or greater, use the $.on() method as instructed above.

Upvotes: 0

SeanCannon
SeanCannon

Reputation: 78046

on() is just a binder that allows for target delegation. It's more of a replacement for delegate() than for live().

$('foo').live('click',fn); is essentially $(document).on('click','foo',fn);

With that in mind, you simply bind the click event to the constant parent wrapper and delegate to your target, like so:

$('span.more-available').on('click', 'a.more', function(){
    var $parent = $(this).parent();
    $parent.text($parent.data('completemessage'));
});

Upvotes: 11

Related Questions