点击具有DOM动态更新的事件

时间:2011-12-01 09:31:22

标签: jquery

我正在玩几个示例来学习jQuery。我做了一个示例,当用户单击add按钮并在单击列表中的任何项目时显示项目列表时,将项目添加到列表中:

代码:

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());
    });
});

问题:

如果用户点击旧项目,则控制台会显示所有项目(旧项目和新项目),但如果用户单击通过单击add按钮创建的新项目,则不会显示这些项目。我假设事件点击符合$itemsList,此对象仅引用脚本加载时创建的项目,但不包括连续创建的项目。

任何建议,消化?

3 个答案:

答案 0 :(得分:2)

var $itemsList = jQuery('#list');

jQuery('#add').click(function(e){
    e.preventDefault();
    jQuery('#list').append('<li>new item</li>');
    $itemsList = jQuery('#list li');
});

$itemsList.on("click","li",function(e){
    e.preventDefault();
    console.log('there are ' + $itemsList.length + ' items');
    $itemsList.each(function(){
        console.log(jQuery(this).text());
    });
});

jQuery 1.7.1

  

ON() - &gt; live()或delegate()

描述:为现在和将来与当前选择器匹配的所有元素附加事件处理程序。

答案 1 :(得分:1)

执行此操作$itemsList.click(...)时,您将事件处理程序绑定到“click”事件,但即使您在“Add”事件处理程序中重新选择列表项,新项也不会自动绑定。

您必须使用事件委派为您点击事件绑定到动态添加的元素。

$('#list').on('click', 'li', clickHandler);

执行此操作可以转换为:在元素#list上委托'click'事件,并仅将事件处理限制为li元素(第二个参数)。

在jquery 1.7中添加了.on()方法。如果您使用该库的先前版本,请使用.delegate()。

注意:忘记弃用的.live()。

.on().delegate()

上的文档

答案 2 :(得分:1)

因为要向DOM添加新项,所以需要使用不同的方法来为它们分配处理程序,因为click()仅用于加载jQuery时可用的DOM元素。

相反,请使用delegate()添加处理程序:

var $itemsList = jQuery('#list li');

jQuery('#add').click(function(e){
    e.preventDefault();
    jQuery('#list').append('<li>new item</li>');
    $itemsList = jQuery('#list li');
});

$("#list").delegate("LI", "click", function(e){
    e.preventDefault();
    $("#total").text('there are ' + $itemsList.length + ' items');
    $itemsList.each(function(){
        console.log(jQuery(this).text());
    });
});

Example fiddle here

或者,如果你使用的是jQuery 1.7+,你可以使用on()代替delegate(),但在这种情况下它们的功能基本相同。