如何删除元素中的所有侦听器?

我有一个按钮,我添加了一些eventlistners到它:

document.getElementById("btn").addEventListener("click", funcA, false);
document.getElementById("btn").addEventListener("click", funcB, false);
document.getElementById("btn").addEventListener("click", funcC, false);
document.getElementById("btn").addEventListener("blur" , funcD, false);
document.getElementById("btn").addEventListener("focus", funcE, false);


<button id="btn">button</button>

我可以通过以下方法删除它们:

document.getElementById("btn").removeEventListener("click",funcA);

如果我想要一次性删除所有侦听器,或者我没有函数引用(funcA),该怎么办?有什么办法吗,还是我得一个一个把它们去掉?

314054 次浏览

我认为最快的方法是克隆节点,这将删除所有事件监听器:

var old_element = document.getElementById("btn");
var new_element = old_element.cloneNode(true);
old_element.parentNode.replaceChild(new_element, old_element);

只是要小心,因为这也将清除有关节点的所有子元素上的事件侦听器,所以如果您想保留它,就必须采用一次显式删除一个侦听器的方法。

如果你正在使用jquery事件,这可以在一行中完成:

jQuery事件(.on()):

$("#myEl").off()

对于本地javascript事件(.addEventListener()):

$('#myEl').replaceWith($('#myEl').clone());

这里有一个例子:

http://jsfiddle.net/LkfLezgd/3/

下面是一个同样基于cloneNode的函数,但有一个选项可以只克隆父节点并移动所有子节点(以保留它们的事件侦听器):

function recreateNode(el, withChildren) {
if (withChildren) {
el.parentNode.replaceChild(el.cloneNode(true), el);
}
else {
var newEl = el.cloneNode(false);
while (el.hasChildNodes()) newEl.appendChild(el.firstChild);
el.parentNode.replaceChild(newEl, el);
}
}

删除一个元素上的事件监听器:

recreateNode(document.getElementById("btn"));

删除一个元素及其所有子元素上的事件监听器:

recreateNode(document.getElementById("list"), true);

如果你需要保留对象本身,因此不能使用cloneNode,那么你必须包装addEventListener函数并自己跟踪监听器列表,就像在这个答案中一样。