【问题标题】:JQuery. Removing all listeners on delegated events查询。删除委托事件的所有侦听器
【发布时间】:2014-03-13 13:15:30
【问题描述】:

我有包含一些元素的容器。他们有一些委托的事件监听器。

这样

$('body').on('click', '.container .button', function() { ... });

我想从容器中的所有元素中删除所有侦听器(无论是什么事件类型和选择器)。

这样

 $( "body" ).off("*", ".container *");

但它不起作用。

有人可以帮忙吗?提前感谢您的帮助。

【问题讨论】:

    标签: javascript jquery events listener


    【解决方案1】:

    更新答案

    在 cmets 中,你说过:

    好的。我有一个 jsfiddle 来解释这个问题。 http://jsfiddle.net/KT42n/3我想从容器中的所有元素中删除所有处理程序

    不幸的是,在我的情况下使用命名空间是不可能的

    哎哟。这将使其变得非常困难,尤其是因为一些委托处理程序可能与容器内外的元素相关。

    想到的唯一一件事是列出您想要阻止的所有事件名称(没有那么多):

    $(".container").on("click mousedown mouseup etc.", false);
    

    这将在事件到达 body 之前停止事件,因此在委托处理程序看到它之前:Live Example

    <!DOCTYPE html>
    <html>
    <head>
    <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
    <meta charset=utf-8 />
    <title>Stop Delegated Handlers Within Container</title>
    </head>
    <body>
      <p>Outside the container</p>
      <div class="container">
        <p>Inside the container</p>
      </div>
      <script>
        (function() {
          // Other handlers
          $("body").on("click", "p", function() {
            display("paragraph clicked");
          });
    
          // Prevent clicks within container
          $(".container").on("click mousedown etc", false);
    
          function display(msg) {
            var p = document.createElement('p');
            p.innerHTML = String(msg);
            document.body.appendChild(p);
          }
        })();
      </script>
    </body>
    </html>
    

    原答案

    您可以像这样从 body 中删除 所有 处理程序:

    $("body").off();
    

    这包括委托的。

    如果您想保留一些处理程序而不保留其他处理程序,我能想到的最简单的方法是在连接事件时为其命名,例如:

    $("body").on("click.foo", "selector", ...);
    

    ...等等。然后你可以使用命名空间来删除​​它们:

    $("body").off(".foo", "selector");
    

    ...甚至只是

    $("body").off(".foo");
    

    ...完全删除所有命名空间,而不仅仅是该选择器的那些。

    例如:Live Copy

    <!DOCTYPE html>
    <html>
    <head>
    <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
    <meta charset=utf-8 />
    <title>Removing All Delegated Handlers</title>
    </head>
    <body>
      <div class="clickable">Click me</div>
      <div class="mousemoveable">Mouse over me</div>
      <input type="button" id="theButton" value="Remove handlers">
      <script>
        (function() {
          $("body").on("click.foo", ".clickable", function() {
            display("click");
          });
          $("body").on("mousemove.foo", ".mousemoveable", function() {
            display("mousemove");
          });
          $("#theButton").click(function() {
            $("body").off(".foo");
          });
          function display(msg) {
            var p = document.createElement('p');
            p.innerHTML = String(msg);
            document.body.appendChild(p);
          }
        })();
      </script>
    </body>
    </html>
    

    【讨论】:

    • 好的。我有一个 jsfiddle 来解释这个问题。 jsfiddle.net/KT42n/3我想从容器中的所有元素中删除所有处理程序
    • @T.J Crowder:希望现在您知道有些签名中的事件名称是可选的,并且单个字符串参数不会始终被视为事件名称。
    • @see613:到目前为止,最好的办法是在连接它们时使用命名空间。否则,您需要遍历body 上的委托处理程序,并查看它们匹配的元素(在那个时间点)是否在容器中,然后删除它们;而且我不认为 jQuery 可以为此提供任何公共 API。此外,同一个委托处理程序可能与容器中的元素相关,而不是与容器中的元素相关,这确实很棘手。
    • @TilwinJoy:我说的是"...一个事件名称和/或事件命名空间..."您的初始答案,第一个10分钟左右,完全错了。您传入的是选择器,而不是命名空间。更新后的答案是可以的,除了是这个答案的副本。如果您要为 SO 做出贡献,那么当您出错时,您将不得不习惯人们在不评论的情况下投反对票(以及在不投反对票的情况下发表评论)。每个人有时都会做错事。把它当作它的本来面目:表明答案是“没用”,而不是对个人的侮辱,你会做得很好。
    • @T.J.Crowder 好吧,您在阅读文档后想出了这个,在此之前您的评论也是“完全错误的”。
    【解决方案2】:

    $("body").unbind()删除所有处理程序

    在 Jquery 在线文档中,它已经提到它删除了所有附加到元素的事件句柄

    使用 .bind() 附加的事件处理程序可以使用 .unbind() 删除。 (从 jQuery 1.7 开始,.on() 和 .off() 方法优先于 在元素上附加和删除事件处理程序。)在最简单的情况下, 没有参数,.unbind() 删除所有附加到 元素:

    链接:http://api.jquery.com/unbind/

    如有错误请指正

    【讨论】:

    • @War10ck:不,那不是真的。但我不知道unbind 会解除与delegateon 挂钩的委托 处理程序。
    【解决方案3】:

    要从元素中移除所有委托事件而不移除非委托事件,您只需使用特殊值 **

    $('body').off('click', '**');

    【讨论】:

      【解决方案4】:

      这可行 http://jsfiddle.net/KT42n/9/

      不幸的是,类似的东西不起作用

       $('body').undelegate('.container > * ','click');
      

      【讨论】:

      • 有些孩子没有身份证怎么办? (因为他们可能会这样做)
      • 我猜你必须用你用过的选择器调用 undelegate/off 到所有项目,并用一个不包括来自 .container 的新选择器调用 delegate/on
      • 也许这可以帮助jsfiddle.net/KT42n/12 我找不到更好的解决方案,因为函数 delgate/on 或 undelegate/off 的选择器都不允许复杂的选择器...
      猜你喜欢
      • 2020-08-27
      • 2018-06-29
      • 1970-01-01
      • 1970-01-01
      • 2018-09-04
      • 1970-01-01
      • 2013-10-28
      • 1970-01-01
      • 2022-08-03
      相关资源
      最近更新 更多