【问题标题】:jquery: how to add event handler to dynamically added element without adding it to existing element againjquery:如何将事件处理程序添加到动态添加的元素而不将其再次添加到现有元素
【发布时间】:2015-05-10 18:31:36
【问题描述】:

我将尝试解释我的问题: 我有一个网站,用户可以在其中动态添加元素。它们都属于“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");
    } 


    });

【问题讨论】:

    标签: javascript jquery html


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 谢谢。编辑了周围的 cmets,这样如果有人再次查看它就不会感到困惑。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      但您也可以定义一个 named 点击处理程序,该处理程序可用于附加到页面加载时已经存在的元素,以及(范围允许)稍后添加的元素。

      你可以选择写...

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

      【讨论】:

        猜你喜欢
        • 2011-08-11
        • 1970-01-01
        • 2019-10-17
        • 2011-06-04
        • 2019-11-13
        • 2011-07-05
        • 2021-06-15
        • 1970-01-01
        • 2014-06-03
        相关资源
        最近更新 更多