用一个新事件覆盖绑定在元素上的所有JavaScript事件

27
假设整个站点上有大量元素,这些元素有未知数量和类型的事件被绑定。
如果我需要用一个绑定事件覆盖所有这些事件,并且只有这个事件会触发,你有什么建议?
我将把事件绑定到一个单击事件处理程序上,并且我使用jQuery。
提前致谢。

1
你的意思是在不实际解绑原始事件处理程序的情况下吗? - user113716
哎呀,这听起来像是一个非常糟糕的想法。不过我怀疑你可以通过弄清楚内部jQuery机制并用自己的代码颠覆它来实现。 - Pointy
@patrick dw - 解除所有原始点击事件处理程序是可以的,只要不需要识别与点击相关联的确切事件。如果有一种方法可以“解除所有点击事件”,然后“绑定此特定的、覆盖的点击事件”,那就太好了。 - jerome
每个事件类型的所有元素都会得到相同的处理程序吗?它们最初是使用 jQuery 绑定的吗?如果不是,它们是如何绑定的? - user113716
4个回答

56

您需要使用jQuery#unbind

要移除一个元素或一组元素上的所有事件处理程序,只需执行以下操作:

$('.some-selector').unbind();

要解除绑定仅针对点击处理程序,请使用unbind('click')

$('.some-selector').unbind('click');

如果要解除所有点击事件的绑定并在解绑之后立即绑定自己的处理程序,可以像这样做:

$('.some-selector').unbind('click').click(function(event) {
  // Your code goes here
});

请注意,这仅适用于使用jQuery绑定的事件(使用.bind或任何使用.bind内部的jQuery方法)。如果您想从给定的一组元素中删除所有可能的onclick事件,您可以使用:

$('.some-selector')
  .unbind('click') // takes care of jQuery-bound click events
  .attr('onclick', '') // clears `onclick` attributes in the HTML
  .each(function() { // reset `onclick` event handlers
    this.onclick = null;
  });

1
这不包括与内联JavaScript或纯JavaScript事件侦听器绑定的事件。 - jAndy
1
如何使用 $(".some-selector").unbind("click").attr("onclick", "").each(function(){ this.onclick = null; }); - Alexander Wallin

8

我希望提供一个想法,不需要完全删除所有事件(只需覆盖它们)。

如果您的新绑定事件(我们称其为“click”)仅针对绑定到的元素,则我认为您可以通过stopPropagation()函数忽略任何其他事件。像这样:

$("specific-selector").on("click", ".specific-class", function (e) {
  e.stopPropagation()
  // e.stopImmediatePropagation()
  /* your code continues ... */
});

它将停止事件冒泡,因此您的其他事件将不会触发。使用stopImmediatePropagation()来防止其他事件附加到与"click"相同的元素上。
例如,如果"mouseleave"事件也绑定到$("specific-selector .specific-class")元素,则它也不会触发。
最后,所有其他事件都不会在该元素上触发,而是在新的"click"元素上。
未解决的问题是,如果其他事件也使用了stopPropagation()怎么办?...那么我认为具有最佳规范的事件将获胜,因此建议避免复杂、太多的事件。
您可以在jQuery网站上查看更多信息关于"直接和委托事件"。

1
尝试使用live代替bind。然后,您可以轻松地从选择器中使用die删除现有绑定,这是一项快速操作,并且同样快速设置另一个实时绑定。
   $('selection here').live('..', .....);  // multiple invocations
   $('selection here').die();
   $('selection here').live('click',.....);

DOM 不会被触碰。事件条件在事件发生时进行评估。

但通常如果您只想交换处理程序函数,为什么不这样做:

var ahandler = function(evt) { /* first implementation */ }
$('.selector').bind('click', function(evt) { ahandler(evt); });

//and then if you want to change handlers
ahandler = function(evt) { /* new implementation */ };

这样做可以完全免费地进行任何更改、重新绑定等操作。


之前在使用别人的代码时,发现它使用了“live”,但我无法弄清如何解除绑定...这个方法让我节省了很多时间和烦恼 ;) - afreeland
1
请注意:live() 方法已被弃用,请改用 on() 方法。建议使用 jQuery 的 on() 方法。 - aikeru

1

看起来这实际上很简单:

$('#foo').unbind('click');
$('#foo').bind('click', myNewFunction);

虽然如此,感谢您的回复。


1
你不需要两个语句,你可以将它们链接在一起(就像我在我的回答中所解释的那样)。 - Mathias Bynens

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接