【问题标题】:Best way to remove an event handler in jQuery?在 jQuery 中删除事件处理程序的最佳方法?
【发布时间】:2010-09-17 13:34:16
【问题描述】:

我有一个input type="image"。这就像 Microsoft Excel 中的单元格注释。如果有人在与此input-image 配对的文本框中输入一个数字,我将为input-image 设置一个事件处理程序。然后,当用户点击image 时,他们会弹出一个小窗口来为数据添加一些注释。

我的问题是,当用户在文本框中输入零时,我需要禁用input-image 的事件处理程序。我尝试了以下方法,但无济于事。

$('#myimage').click(function { return false; });

【问题讨论】:

    标签: jquery html-input


    【解决方案1】:

    我知道这来晚了,但是为什么不使用普通的 JS 来删除事件呢?

    var myElement = document.getElementById("your_ID");
    myElement.onclick = null;
    

    或者,如果您使用命名函数作为事件处理程序:

    function eh(event){...}
    var myElement = document.getElementById("your_ID");
    myElement.addEventListener("click",eh); // add event handler
    myElement.removeEventListener("click",eh); //remove it
    

    【讨论】:

    • 好建议,我更喜欢在可用时使用本机 javascript
    【解决方案2】:

    如果您使用$(document).on() 将侦听器添加到动态创建的元素,那么您可能必须使用以下方法将其移除:

    // add the listener
    $(document).on('click','.element',function(){
        // stuff
    });
    
    // remove the listener
    $(document).off("click", ".element");
    
    

    【讨论】:

    • 我在 jquery 数据表行上有一个点击事件。从 Web API 加载的数据。所以,就我而言,这个解决方案效果很好:)
    【解决方案3】:

    remove ALL event-handlers,这对我有用:

    删除所有事件处理程序意味着将普通的HTML structure 没有附加到element 及其child nodes 上的所有event handlers。为此,jQuery's clone() 提供了帮助。

    var original, clone;
    // element with id my-div and its child nodes have some event-handlers
    original = $('#my-div');
    clone = original.clone();
    //
    original.replaceWith(clone);
    

    有了这个,我们将用clone 代替没有event-handlersoriginal

    祝你好运……

    【讨论】:

      【解决方案4】:

      jQuery ≥ 1.7

      从 jQuery 1.7 开始,事件 API 已更新,.bind()/.unbind() 仍可用于向后兼容,但首选方法是使用 on()/off() 函数。下面是,

      $('#myimage').click(function() { return false; }); // Adds another click event
      $('#myimage').off('click');
      $('#myimage').on('click.mynamespace', function() { /* Do stuff */ });
      $('#myimage').off('click.mynamespace');
      

      jQuery

      在您的示例代码中,您只是向图像添加另一个点击事件,而不是覆盖前一个:

      $('#myimage').click(function() { return false; }); // Adds another click event
      

      这两个点击事件都会被触发。

      正如人们所说,您可以使用 unbind 删除所有点击事件:

      $('#myimage').unbind('click');
      

      如果您想添加单个事件然后将其删除(不删除可能已添加的任何其他事件),那么您可以使用事件命名空间:

      $('#myimage').bind('click.mynamespace', function() { /* Do stuff */ });
      

      并仅删除您的活动:

      $('#myimage').unbind('click.mynamespace');
      

      【讨论】:

      • 有没有办法测试unbind() 是否有效?我已经添加了它,两个事件仍在触发。
      • 好吧,如果两个事件仍在触发,那么显然它不起作用。您必须提供更多信息才能获得正确的答案。尝试提出一个单独的问题。
      • 旧答案-也喜欢包含的命名空间信息-但我忘记了;开/关是否返回 jQ 对象?如果是这样,也许更完整的答案是菊花链:$('#myimage').off('click').on('click',function(){...})
      • 是的,他们这样做了,所以是的,如果您想清除所有其他点击事件,然后添加您自己的事件,您可以执行上述链接调用。
      • 使用 .unbind() 在我切换一堆复选框的情况下帮助了我,但我意识到我反复重新添加 .click() 处理程序,导致应用程序挂起。
      【解决方案5】:

      如果 .on() 方法以前与特定选择器一起使用,如下例所示:

      $('body').on('click', '.dynamicTarget', function () {
          // Code goes here
      });
      

      unbind().off() 方法都不会工作。

      但是,.undelegate() 方法可以用于从事件中完全删除与当前选择器匹配的所有元素的处理程序:

      $("body").undelegate(".dynamicTarget", "click")
      

      【讨论】:

      • 我滚动整个页面,同时寻找这个解决方案,就像一个魅力。
      【解决方案6】:

      希望我下面的代码能解释一切。 HTML:

      (function($){
      
           $("#btn_add").on("click",function(){
             $("#btn_click").on("click",added_handler);
             alert("Added new handler to button 1");
           });
      
        
       
           $("#btn_remove").on("click",function(){
             $("#btn_click").off("click",added_handler);
             alert("Removed new handler to button 1");
           });
      
        
         function fixed_handler(){
          alert("Fixed handler");
        }
        
         function added_handler(){
          alert("new handler");
        }
        
        $("#btn_click").on("click",fixed_handler);
        $("#btn_fixed").on("click",fixed_handler);
        
        
      })(jQuery);
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <button id="btn_click">Button 1</button>
        <button id="btn_add">Add Handler</button>
        <button id="btn_remove">Remove Handler</button>
        <button id="btn_fixed">Fixed Handler</button>

      【讨论】:

      • 既然已经可以全局访问,为什么还要将})(jQuery); 传入IIFE?
      • 好问题,布莱恩。由于实践,这种方法已经进入我的基因。 - 非 jquery 插件可能有变量 $,因此我不能直接使用 $。 - 在 js 脚本文件中频繁使用单词“jQuery”会增加文件的字节大小,其中 jQuery 是一个 6 字节的字符串。因此我更喜欢使用“$”或任何单字节变量。
      【解决方案7】:

      您可能会将onclick 处理程序添加为内联标记:

      <input id="addreport" type="button" value="Add New Report" onclick="openAdd()" />
      

      如果是这样,jquery .off().unbind() 将不起作用。您还需要在 jquery 中添加原始事件处理程序:

      $("#addreport").on("click", "", function (e) {
         openAdd();
      });
      

      那么jquery就有了对事件处理程序的引用,可以将其移除:

      $("#addreport").off("click")
      

      VoidKing 在上面的评论中稍微倾斜地提到了这一点。

      【讨论】:

        【解决方案8】:

        如果您通过html 设置onclick,则需要removeAttr ($(this).removeAttr('onclick'))

        如果您通过 jquery 设置它(如我上面示例中的第一次单击之后),那么您需要 unbind($(this).unbind('click'))

        【讨论】:

          【解决方案9】:

          删除内联 onclick 事件的最佳方法是 $(element).prop('onclick', null);

          【讨论】:

            【解决方案10】:

            2014 年更新

            使用最新版本的 jQuery,您现在只需执行 $( "#foo" ).off( ".myNamespace" ); 即可取消绑定命名空间中的所有事件

            【讨论】:

              【解决方案11】:

              所有描述的方法都对我不起作用,因为我正在将带有on() 的点击事件添加到在运行时创建元素的文档中:

              $(document).on("click", ".button", function() {
                  doSomething();
              });
              


              我的解决方法:

              由于我无法解除“.button”类的绑定,我只是将另一个类分配给具有相同 CSS 样式的按钮。通过这样做,live/on-event-handler 最终忽略了点击:

              // prevent another click on the button by assigning another class
              $(".button").attr("class","buttonOff");
              

              希望对您有所帮助。

              【讨论】:

                【解决方案12】:

                如果事件被以这种方式附加,并且目标是未附加的:

                $('#container').on('click','span',function(eo){
                    alert(1);
                
                    $(this).off(); //seams easy, but does not work
                
                    $('#container').off('click','span'); //clears click event for every span
                
                    $(this).on("click",function(){return false;}); //this works.
                
                });​
                

                【讨论】:

                  【解决方案13】:

                  这也很好用。简单易行。见http://jsfiddle.net/uZc8w/570/

                  $('#myimage').removeAttr("click");
                  

                  【讨论】:

                    【解决方案14】:

                    这可以通过使用 unbind 函数来完成。

                    $('#myimage').unbind('click');
                    

                    您可以在 jquery 中为同一个对象和事件添加多个事件处理程序。这意味着添加新的并不会替换旧的。

                    有几种更改事件处理程序的策略,例如事件命名空间。在线文档中有一些关于此的页面。

                    看看这个问题(这就是我了解 unbind 的方式)。答案中对这些策略进行了一些有用的描述。

                    How to read bound hover callback functions in jquery

                    【讨论】:

                      【解决方案15】:

                      我必须使用 prop 和 attr 将事件设置为 null。我不能用一个或另一个来做到这一点。我也无法让 .unbind 工作。我正在研究一个 TD 元素。

                      .prop("onclick", null).attr("onclick", null)
                      

                      【讨论】:

                      • 我投了赞成票,因为我已经尝试解除绑定 onblur 大约 30 分钟。 '.unbind' 不起作用,'.prop' 不起作用,'.attr' 不起作用,但是这个把 .prop 和 .attr 放在一起的技巧就成功了。奇怪的。我正在使用 Chrome 和 jquery 1.7.2
                      • 这里也一样。使用 jq 1.7.2 和 .prop("onclick", null) 在 FF 上对我来说 unbind 和 off 不起作用
                      • 我认为上述方法对你们不起作用的原因是因为您的设置方式。如果您将事件处理程序写入 DOM,那么是的,清除此属性是清除事件处理程序所必需的,但是,我认为大多数人(包括我自己)希望将这些东西(javascrip、事件处理程序等)排除在外DOM,所以当我们想要设置一个事件处理程序时,我们使用类似$("#elementId").click(function(){//Event execution code goes here}); 这样它根本不在 html 页面中。为了明确我们实际上需要使用.unbind(),或者首选的.off()
                      • 这是一个刚刚花了一个小时才发现通过 jQuery 添加的属性没有显示在 Chrome 的元素面板上的人的赞。一直在尝试unbindoff,但并没有解决问题。非常感谢!
                      【解决方案16】:

                      如果您想只响应一次事件,以下语法应该非常有用:

                       $('.myLink').bind('click', function() {
                         //do some things
                      
                         $(this).unbind('click', arguments.callee); //unbind *just this handler*
                       });
                      

                      使用 arguments.callee,我们可以确保删除一个特定的匿名函数处理程序,从而为给定事件提供一个时间处理程序。希望这对其他人有帮助。

                      【讨论】:

                      • 当然可以,尽管有时您可能希望对何时应该解除绑定处理程序有一定的逻辑(例如,除非他们先归档文本框,否则不要解除绑定)。
                      • arguments.callee 在严格模式下被废弃!
                      【解决方案17】:

                      感谢您的信息。非常有帮助,我用它来锁定另一个用户在编辑模式下的页面交互。我将它与 ajaxComplete 结合使用。不一定是相同的行为,但有些相似。

                      function userPageLock(){
                          $("body").bind("ajaxComplete.lockpage", function(){
                              $("body").unbind("ajaxComplete.lockpage");
                              executePageLock();      
                          });
                      };  
                      
                      function executePageLock(){
                          //do something
                      }
                      

                      【讨论】:

                        【解决方案18】:

                        回答此问题时此功能不可用,但您也可以使用live() 方法启用/禁用事件。

                        $('#myimage:not(.disabled)').live('click', myclickevent);
                        
                        $('#mydisablebutton').click( function () { $('#myimage').addClass('disabled'); });
                        

                        这段代码会发生什么,当您单击#mydisablebutton 时,它会将禁用的类添加到#myimage 元素中。这将使选择器不再与元素匹配,并且在删除“禁用”类使 .live() 选择器再次有效之前不会触发事件。

                        通过添加基于该类的样式还有其他好处。

                        【讨论】:

                        • 使用 live() 的好方法,以前从未想过以这种方式使用它...除了编码方便之外,它是否更快,或者它是否提供了使用绑定/取消绑定的任何其他优势?跨度>
                        • 如果您要添加/删除元素,那么与绑定相比有明显的性能优势,因为与 live 的绑定只进行一次。 jQuery 似乎正在转向更多的活动和委托事件,而不是绑定到特定元素。
                        • 要禁用 live 你可以使用 die()
                        • "从 jQuery 1.7 开始,不推荐使用 .live() 方法。使用 .on() 附加事件处理程序。旧版本 jQuery 的用户应优先使用 .delegate() 而不是 .live ()。” api.jquery.com/live
                        • 啊,善变的 jQuery,有一天你给一个人带来了 300 个代表,第二天它就过时了。
                        【解决方案19】:

                        也许 unbind 方法对你有用

                        $("#myimage").unbind("click");
                        

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 2011-01-25
                          • 2012-09-04
                          • 1970-01-01
                          • 2010-11-21
                          • 1970-01-01
                          • 1970-01-01
                          相关资源
                          最近更新 更多