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


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

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

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

971
2017-10-16 15:28


起源




答案:


jQuery≥1.7

随着jQuery 1.7的推出,事件API已经更新, .bind()/.unbind() 仍可用于向后兼容,但首选方法是使用 上()/关闭() 功能。以下是现在,

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

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

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

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

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

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

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

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

并删除您的活动:

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

1495
2017-10-16 21:13



有没有办法测试是否 unbind() 工作中?我添加了它,两个事件仍然在发射。 - David Yell
好吧,如果两个事件仍在解雇,那么显然它不起作用。您必须提供更多信息才能获得正确答案。试着问一个单独的问题。 - samjudson
旧答案 - 也就像包含的命名空间信息一样 - 但我忘了; on / off返回jQ对象?如果是这样,或许更完整的答案将是菊花链: $('#myimage').off('click').on('click',function(){...}) - vol7ron
是的,他们这样做,所以是的,如果您想清除所有其他点击事件然后添加自己的事件,您可以进行上述链式调用。 - samjudson
removeAttr('onclick')为我工作。 - Barry Guvenkaya


当这个问题得到解答时,这是不可用的,但你也可以使用 生活() 启用/禁用事件的方法。

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

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

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

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


59
2017-07-23 17:57



很好的使用方式 live()从来没有想过以这种方式使用它...除了编码方便之外,它是否更快或者它是否提供使用bind / unbind的任何其他优点? - chakrit
如果要添加/删除元素,那么与bind相比,有明确的性能优势,因为与live的绑定只执行一次。 jQuery似乎正在转向更多的实时和委托事件,而不是绑定到特定元素。 - MacAnthony
要禁用live,你可以使用die() - Moons
“从jQuery 1.7开始,不推荐使用.live()方法。使用.on()来附加事件处理程序。旧版jQuery的用户应优先使用.delegate(),而不是.live()。” api.jquery.com/live - Lucas Pottersky
啊,变幻无常的jQuery,有一天你带300代表一个人,第二天它已经过时了。 - MrBoJangles


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

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

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

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

看看这个问题(这就是我学习unbind的方法)。答案中对这些策略有一些有用的描述。

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


37
2017-10-16 15:35





如果你想回复一个事件 就一次,以下语法应该是非常有用的:

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

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

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


34
2017-08-05 07:29



jQuery已经有了 jQuery#one('click', fn) 为了这。 - Andy E
当然,尽管有时您可能希望对处理程序何时应该解除绑定有一定的逻辑(例如,除非他们首先提交文本框,否则不要解除绑定)。 - ghayes
arguments.callee在严格模式下被删除! - zloctb


也许unbind方法适合你

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

29
2017-10-16 15:31





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

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

29
2018-03-28 14:44



我投了这票,因为我一直试图解开一个大约30分钟的onblur。 '.unbind'不起作用,'。prop'不起作用,'。attr'不起作用,但是.prop和.attr这两个技巧合起来了。奇。我正在使用Chrome和jquery 1.7.2 - Jeremy
同样在这里!我试图从简单的<a>标签中删除click事件! Thanx为此。在我的情况下.prop(“onclick”,null)就足够了。 - Jan Saladukha
同样在这里。使用jq 1.7.2和.prop(“onclick”,null)在FF上取消绑定和关闭对我来说也不适用于我的情况 - bryanallott
我认为上述方法对你们不起作用的原因是因为你如何设置它。如果您将事件处理程序写入DOM然后是,清除此属性对于清除事件处理程序是必要的,但是,我认为大多数人(包括我自己)希望保留这些内容(javascrip,事件处理程序等)。 DOM,所以当我们想要设置一个事件处理程序时,我们会使用类似的东西 $("#elementId").click(function(){//Event execution code goes here}); 所以它根本不在html页面中。要明确我们确实需要使用 .unbind(),或者首选 .off() - VoidKing
这里有一个人花了一个小时才发现通过jQuery添加的属性没有显示在Chrome的元素面板上。一直在尝试 unbind和 off 它没有解决问题。非常感谢你! - Renan


你可能正在添加 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在上面的评论中更倾向于提到这一点。


10
2018-01-21 22:25





如果事件被附加 这条路,目标是独立的:

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

});​

9
2018-06-26 13:02