在jQuery中删除事件处理程序的最佳方法?


1053

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

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

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

Answers:


1626

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 <1.7

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

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

然后,两个点击事件都会被触发。

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

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

如果要添加一个事件然后将其删除(而不删除可能已添加的其他事件),则可以使用事件命名空间:

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

并删除您的事件:

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

6
有没有一种方法可以测试是否unbind()正常?我添加了它,两个事件仍在触发。
David Yell 2010年

19
好吧,如果两个事件仍在触发,则显然它不起作用。您必须提供更多信息才能获得正确的答案。尝试问一个单独的问题。
samjudson,2010年

13
旧答案-也像包含的名称空间信息一样-但我忘记了;开/关返回jQ对象?如果是这样,一个菊链也许是一个更完整的答案:$('#myimage').off('click').on('click',function(){...})
vol7ron 2013年

3
是的,他们会这样做,所以是的,如果您想清除所有其他单击事件然后添加自己的事件,则可以进行上述链接的呼叫。
samjudson

.unbind()在我要切换一堆复选框,但关系到我要.click()反复添加处理程序的情况下,使用帮助了我,导致应用程序挂起。
TecBrat 2014年

63

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

$('#myimage:not(.disabled)').live('click', myclickevent);

$('#mydisablebutton').click( function () { $('#myimage').addClass('disabled'); });

此代码将发生的事情是,当您单击#mydisablebutton时,它将把禁用的类添加到#myimage元素中。这样可以使选择器不再与该元素匹配,并且直到删除'disabled'类使.live()选择器再次有效之前,该事件才不会触发。

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


3
很好的使用方式live(),以前从未考虑过使用它...除了编码方便之外,它是否更快或是否提供了使用绑定/取消绑定的任何其他优势?
chakrit

2
如果要添加/删除元素,则与bind相比,它具有明显的性能优势,因为与live的绑定仅执行一次。jQuery似乎正在转移到更多实时事件和委托事件,而不是绑定到特定元素。
MacAnthony 2010年

3
要禁用直播,您可以使用die()
Moons

9
“从jQuery 1.7开始,不推荐使用.live()方法。请使用.on()附加事件处理程序。jQuery较早版本的用户应优先使用.delegate()而不是.live()。” api.jquery.com/live
Lucas Pottersky '12

12
啊,善变的jQuery,有一天您会给一个家伙带来300个报告,第二天就已经过时了。
MrBoJangles

37

如果你想回应的事件只是一个时间,下面的语法应该是非常有帮助:

 $('.myLink').bind('click', function() {
   //do some things

   $(this).unbind('click', arguments.callee); //unbind *just this handler*
 });

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


2
绝对可以,尽管有时您可能希望对何时取消绑定处理程序具有一定的逻辑(例如,除非他们首先提交了文本框,否则不要取消绑定)。
ghayes

5
arguments.callee在严格模式下不赞成使用!
zloctb

37

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

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

您可以将多个事件处理程序添加到jquery中的同一对象和事件。这意味着添加新的不能替代旧的。

有几种更改事件处理程序的策略,例如事件名称空间。联机文档中有一些与此有关的页面。

看一下这个问题(这就是我学会解除绑定的方式)。答案中对这些策略有一些有用的描述。

如何在jQuery中读取绑定的悬停回调函数



30

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

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

1
我之所以投票赞成这是因为我一直在尝试取消onblur的绑定约30分钟。'.unbind'不起作用,'。prop'不起作用,'。attr'不起作用,但是同时将.prop和.attr一起使用的这个技巧可以解决这个问题。奇。我正在将Chrome与jquery 1.7.2结合使用
杰里米(Jeremy)

同样在这里!我试图从简单的<a>标记中删除click事件!对此表示感谢。就我而言,.prop(“ onclick”,null)就足够了。
Jan Lobau,2012年

同样在这里。在我的案例中,jq 1.7.2和.prop(“ onclick”,null)在FF上对unFFC来说,unbind和off对我不起作用
bryanallott 2013年

4
我认为上述方法对您不起作用的原因是您的设置方式。如果您将事件处理程序写入DOM,则是的,清除该属性对于清除事件处理程序是必要的,但是,我认为大多数人(包括我自己)都希望将此类内容(javascrip,事件处理程序等)排除在外。 DOM,因此当我们想要设置事件处理程序时,我们使用类似的东西$("#elementId").click(function(){//Event execution code goes here});,使得它根本不在html页面中。要清除我们确实需要使用.unbind(),或首选.off()
VoidKing

这就像刚刚花了一个小时才发现通过jQuery添加的属性未显示在Chrome的元素面板上的某人一样。一直在尝试unbindoff但并没有解决问题。非常感谢你!
雷南2014年

13

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

$('#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.

});​

11

您可能将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在上面的评论中更倾斜地提到了这一点。


9

2014年更新

使用最新版本的jQuery,您现在只需执行以下操作即可解除绑定命名空间上的所有事件 $( "#foo" ).off( ".myNamespace" );



8

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

删除所有事件处理程序意味着要具有HTML structure没有所有event handlers附加到element和及其的平原child nodes。为此,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取代上面original没有event-handlers的东西了。

祝好运...


7

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

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

function executePageLock(){
    //do something
}

5

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

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

这两个unbind().off()方法都没有去上班。

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

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

1
在滚动查找该解决方案时,我滚动了整个页面,效果非常好。
Abhishek Pandey

4

如果用于$(document).on()向动态创建的元素添加侦听器,则可能必须使用以下命令将其删除:

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

// remove the listener
$(document).off("click", ".element");


2

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

如果您通过jquery进行设置(如上述示例中第一次单击后的设置),则需要 unbind($(this).unbind('click'))


2

我知道这很晚,但是为什么不使用纯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
Michiel

1

所描述的所有方法都不适合我,因为我将click事件添加on()到了在运行时创建元素的文档中:

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


我的解决方法:

由于我无法解除对“ .button”类的绑定,因此我为具有相同CSS样式的按钮分配了另一个类。这样,活动/事件处理程序最终忽略了点击:

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

希望能有所帮助。


1

希望我下面的代码能解释所有问题。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>


1
为什么})(jQuery);已经可以全局访问的IIFE 传递给您 ?
Bryan P

2
好问题,布莱恩。由于实践,该方法已输入我的基因中。-非jquery插件可能有$变量,因此我不能直接使用$。-在js脚本文件中经常使用单词“ jQuery”会增加文件的字节大小,其中jQuery是6字节的字符串。因此,我更喜欢使用“ $”或任何单字节变量。
mysticmo '16

0

只需将其从按钮中删除:

$('.classname').click(function(){
$( ".classname" ).remove();
});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.