代码之家  ›  专栏  ›  技术社区  ›  Thomas Mavrofides

jQuery取消绑定事件处理程序不工作

  •  1
  • Thomas Mavrofides  · 技术社区  · 7 年前

    我正在动态地将节点(div)添加到DOM树中,并通过jQuery(委托或不委托)附加事件侦听器。问题是,我无法解开这些听众的束缚,结果,他们堆积起来了。这是一个示例代码,我找不到任何错误:

    $(function() {
      var theTXT = '<div data-abc="tester">click here</div>';
      $("#loader").on('click', doClick);
      function doClick() {
        $("body").append(theTXT);
        $('[data-abc="tester"]').off('click', redoClick);
        $('[data-abc="tester"]').on('click', redoClick);
        function redoClick() {
          console.log("hi");
        }
      }
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="loader">load</div>

    现在,如果我将redoClick()处理程序移到doClick()处理程序之外,一切正常。 任何帮助都将不胜感激,以便我能理解原因。off()不起作用。

    2 回复  |  直到 7 年前
        1
  •  0
  •   Ziv Weissman    7 年前

    问题不在于“关闭”,而在于事件处理程序。

    因为您是在函数内定义它,所以在函数调用结束后它将“超出范围”,因此关闭不能关闭此特定处理程序。

    如果您将其放置在按计划工作的功能之外,另一种选择是将其删除:

    $(function() {
      var theTXT = '<div data-abc="tester">click here</div>';
      $("#loader").on('click', doClick);
      function doClick() {
        $("body").append(theTXT);
        $('[data-abc="tester"]').off('click'); //remove the handler
        $('[data-abc="tester"]').on('click', redoClick);
        function redoClick() {
          console.log("hi");
        }
      }
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="loader">load</div>

    现在,如果我将redoClick()处理程序移到doClick()处理程序之外, 一切正常。

    因为它是在函数外部声明的,所以。off可以访问它。

    但我的问题是:come on()是如何工作的?我错过了什么?

    第一次单击时,将有一个处理程序,例如doClick#1,首先“off”将尝试删除doClick#1(未绑定)-然后on将单击,绑定doClick#1。第二次运行时,您将创建doClick#2,再次关闭将尝试删除doClick#2-找不到,而打开将添加doClick#2(因此您将有#1+#2,依此类推)

        2
  •  0
  •   Thomas Mavrofides    7 年前

    好吧,恕我直言,具体问题的答案(即如何不将事件侦听器重新连接到一组元素)非常简单。今天早上我突然想到了。而不是使用

    $('[data-abc="tester"]').on('click', redoClick);
    

    我应该使用:

    $('[data-abc="tester"]').last().on('click', redoClick);
    

    成功了,不需要off()