I’m playing with a few samples to learn jQuery. I made an example to add items to a list when user clicks an add button and display items list when they click in any item of the list:
The code:
HTML
<div id="sample"></div>
<a id="add" href="#">Add</a>
<ul id="list">
<li>old item</li>
<li>old item</li>
<li>old item</li>
</ul>
</div>
jQuery
var $itemsList = jQuery('#list li');
jQuery('#add').click(function(e){
e.preventDefault();
jQuery('#list').append('<li>new item</li>');
$itemsList = jQuery('#list li');
});
$itemsList.click(function(e){
e.preventDefault();
console.log('there are ' + $itemsList.length + ' items');
$itemsList.each(function(){
console.log(jQuery(this).text());
});
});
The problem:
If the user clicks in old items, the console displays all items (old and new), but if the user clicks in new items, created by clicking the add button, they are not being displayed. I’m assuming that the event click was asigned to $itemsList, and this object only refers to items created when script loads but not with successive created items.
Any advice, sugestions?
When doing this
$itemsList.click(...)you bind an event handler to the ‘click’ event, but even if you re-select the list items in the ‘Add’ event handler, new items are not binded automatically.You have to use event delegation for you click event to binded to elements added dynamically.
Doing this can be translated into: delegate the ‘click’ event on the element #list, and restrain the event handling to
lielements only (second parameter).The .on() method was added in jquery 1.7. In case you use a prior version of the library, use .delegate().
Note: forget about .live() which is deprecated.
Documentation on .on() and .delegate()