如何删除某些元素的所有事件侦听器而不使用其子元素

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何删除某些元素的所有事件侦听器而不使用其子元素相关的知识,希望对你有一定的参考价值。

我怎么能删除例如$('table td')的事件监听器,而不是它的子元素事件监听器? (我的单元格中有一个带按钮的表)我用.off()尝试了它,但它不起作用。

编辑:例如,我有一个表格单元格,其中包含一些文本和一个按钮。现在tdbutton有自己的事件听众。我想删除td的事件监听器,而不删除button的事件监听器。我知道我可以在删除之后将事件监听器添加回按钮,但该解决方案会在我的情况下引起很多问题。

答案

我猜你已经看过像this one这样的答案,因为你提到不删除子元素上的事件监听器。当然,执行深度克隆将无法正常工作,但可行的方法是执行浅层克隆,然后将子节点传输到克隆。这是一个更多的工作,但它会做你想要的。

主要工作是在setTimeout,所有其余的只是设置。

这里我附加了两个click事件监听器:一个用于按钮,另一个用于容器div。在5秒setTimeout之前,单击该按钮将触发两个侦听器(因此您将看到BUTTON和DIV的控制台日志)。在计时器之后,你仍然会看到BUTTON事件。

var rem = document.getElementById('rem');
var btn = document.getElementById('btn');
function onClick(e) {
  var t = e.currentTarget
  console.log(t.tagName);
}
rem.addEventListener('click', onClick);
btn.addEventListener('click', onClick);

setTimeout(() => {
  console.log('removing events from div');

  // shallow clone
  var rem2 = rem.cloneNode(false);

  // make and extract range to doc fragment 
  // for all contents of original div
  var range = document.createRange(); 
  range.setStartBefore(rem.firstChild);
  range.setEndAfter(rem.lastChild);
  var documentFragment = range.extractContents();

  // append doc fragment to clone
  // insert clone and remove old div
  rem2.appendChild(documentFragment);
  document.body.insertBefore(rem2, rem);
  rem.remove();
}, 5000);
<div id='rem'>
  <h3>Heading</h3>
  <button id='btn'>click me</button>
  <p>paragraph <b>bold</b> stuff</p>
</div>
另一答案

我终于使用命名空间作为on('click.namespace', function(){...})。谢谢你的帮助!

以上是关于如何删除某些元素的所有事件侦听器而不使用其子元素的主要内容,如果未能解决你的问题,请参考以下文章

如何在 javascript 中为所有事件添加事件侦听器而不单独列出它们?

在单页应用程序中取消绑定事件侦听器和删除子元素的正确方法是啥?

移除一个元素是不是也会移除它的事件监听器? [复制]

在动态创建的元素上添加事件监听器

移除类添加的事件监听器

WPF附加事件定义