"on" does not bind to dynamically added items
My html
<div> <span class="more-available" data-completeMessage="This is the complete message you see after clicking more">Hello</span> </div>
I add the anchor tag to the end dynamically, and then I want to attach the click handler to the anchor tag. Therefore i do it
$(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" with "live", it works . (but living is depreciating)
I know I can do it
$(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 ...
Am I mistaken in assuming that "on" provides all the functionality live? Is "on" related to future elements? Is this the right behavior, or am I doing something wrong.
on()
is just a binder that allows you to delegate a goal. This is more of a replacement for delegate()
than for live()
.
$('foo').live('click',fn);
essentially $(document).on('click','foo',fn);
With this in mind, you simply bind the click event to the constant parent shell and delegate its goals, for example:
$('span.more-available').on('click', 'a.more', function(){ var $parent = $(this).parent(); $parent.text($parent.data('completemessage')); });
Use it as 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 a specific selector, meaning that the handle will be delegated when the event fires for the corresponding selector. In the above example, you add a listener to span.more-available
, which the handler will only execute when the a.more
match selector a.more
.
In short, follow the two steps to replace .live
with .on
,
- Find the closest parent elements to which the element will be added dynamically.
- Bind the handler to the parent element using the dynamic element switch as the second argument.
According to jQuery documentation for the $.live()
method:
As with jQuery 1.7, the .live () method is deprecated. Use .on () to attach event handlers. Users of older versions of jQuery should use .delegate () in the .live () preference.
The documentation for $.live()
further provides the methods and syntax used for successors to this method:
Rewriting the .live () method in terms of its successors is simple; these are templates for equivalent calls for all three ways of nesting events:
$(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 are using jQuery 1.7 or higher, use the $.on()
method as above.