jquery:如何将事件处理程序添加到动态添加的元素,而不再将其添加到现有元素

时间:2015-05-10 09:32:29

标签: javascript jquery html

我会尝试解释我的问题: 我有一个用户动态添加元素的网站。它们都属于“toBuy”类。每当向该类添加一个新元素时,我需要将一个单击处理程序仅附加到此元素,而不是附加到所有其他元素。为了保持我的代码清洁,我希望有一个功能来完成这项工作。这是我尝试过的:

这是添加内容的方式:

$("#addItemButton").click(function(){
            var item= $('#item').val();
            $('#item').val("");
            var quantity= $('#quantity').val();
            $('#quantity').val("");
            var comment=$('#addComment').val();
            $('#addComment').val("");
            //construct new html
            var newitem="<div class='toBuyItem'><div class='item'>";
            newitem+=item;
            newitem+="</div><div class='quantity'>";
            newitem+=quantity; 
            newitem+="</div><div class='comment'><img src='img/comment";
            if(comment==""){
                newitem+="_none"
            }
            newitem+=".png' alt='Comment'></div><div class='itemComment'>"
            newitem+=comment;
            newitem+="</div></div>";

            $("#toBuyItems" ).prepend( newitem );
            toggle("#addItemClicked");
            initializeEventListeners();
        });

然后这是initializeEventListeners函数(我也在页面加载时运行,以便现有元素已经具有事件处理程序:

function initializeEventListeners(){
        $(".toBuyItem").click(function(){
            console.log($(this).html());
            console.log($(this).has('.itemComment').length);
            if($(this).has('.itemComment').length != 0){
                console.log("toggling");
                $(this).addClass("toggling");
                toggle(".toggling .itemComment");
                $(this).removeClass("toggling");
            }          
        });
    }
function toggle(item){

        $( item ).slideToggle(500);
    }

现在显然发生的事情是,当添加一个新元素时,现有元素会获得一个新的事件处理程序来进行单击(因此它们有两次)。这意味着只需单击一下即可打开和关闭它们。可能它很简单,但我无法绕过它......

编辑: 所以这有效:

$(document).on('click', '.toBuyItem', function(){
    if($(this).has('.itemComment').length != 0){
        console.log("toggling");
        $(this).addClass("toggling");
        toggle(".toggling .itemComment");
        $(this).removeClass("toggling");
    } 


    });

3 个答案:

答案 0 :(得分:1)

使用jquery&#39; on方法。这样您只需添加event一次。这将自动添加到动态添加的元素中。

$(document/parentSelector).on('click', '.toBuyItem', function() {
    // Event handler code here
});

如果您在上述语法中使用parentSelector,则必须在添加事件时出现。

文档:https://api.jquery.com/on

答案 1 :(得分:0)

您可以使用jQuery.on method。它可以将处理程序附加到DOM中现有的所有处理程序,并在将来的选择器标记中创建。语法如下:

$(document).on('click', '.toBuyItem', function(){
//do onClick stuff
})

答案 2 :(得分:0)

正如其他人所建议的那样,您可以将点击处理委托给document或某些合适的容器元素,这可能就是我要做的事情。

但您可以选择定义命名的点击处理程序,该处理程序可以附加到页面加载中已存在的元素,并且(范围允许)添加到稍后添加的元素。

您可以选择写...

function buy() {
    if($(this).has('.itemComment').length != 0) {
        $(this).addClass("toggling");
        toggle(".toggling .itemComment");
        $(this).removeClass("toggling");
    }
}
function initializeEventListeners() {
    $(".toBuyItem").on('click', buy);
}
$("#addItemButton").on('click', function() {
    var item = $('#item').val(),
        quantity = $('#quantity').val(),
        comment = $('#addComment').val();
    $('#item', '#quantity', '#addComment').val("");
    //construct and append a new item
    var $newitem = $('<div class="toBuyItem"><div class="item">' + item + '</div><div class="quantity">' + quantity + '</div><div class="comment"><img alt="Comment"></div><div class="itemComment">' + comment + '</div></div>').prependTo("#toBuyItems").on('click', buy);// <<<<< here, you benefit from having named the click handler
    $newitem.find(".comment img").attr('src', comment ? 'img/comment.png' : 'img/comment_none.png');
    toggle("#addItemClicked");
});