Javascript/DOM:如何删除 DOM 对象的所有事件侦听器? [英] Javascript/DOM: How to remove all event listeners of a DOM object?
问题描述
只是问题:有没有办法完全删除对象的所有事件,例如一个div?
Just question: Is there any way to completely remove all events of an object, e.g. a div?
我添加每个 div.addEventListener('click',eventReturner(),false);
一个事件.
I'm adding per div.addEventListener('click',eventReturner(),false);
an event.
function eventReturner() {
return function() {
dosomething();
};
}
我找到了一种有效的方法,但不能用于我的情况:
I found a way, which is working, but not possible to use for my case:
var returnedFunction;
function addit() {
var div = document.getElementById('div');
returnedFunction = eventReturner();
div.addEventListener('click',returnedFunction,false); //You HAVE to take here a var and not the direct call to eventReturner(), because the function address must be the same, and it would change, if the function was called again.
}
function removeit() {
var div = document.getElementById('div');
div.removeEventListener('click',returnedFunction,false);
}
推荐答案
我不确定您对删除所有事件的意思.删除特定类型事件的所有处理程序还是删除一种类型的所有事件处理程序?
I am not sure what you mean with remove all events. Remove all handlers for a specific type of event or all event handlers for one type?
如果您想删除所有事件处理程序(任何类型),您可以 克隆元素并用它的克隆替换它:
If you want to remove all event handlers (of any type), you could clone the element and replace it with its clone:
var clone = element.cloneNode(true);
注意:这将保留属性和子项,但不会保留对 DOM 属性的任何更改.
Note: This will preserve attributes and children, but it will not preserve any changes to DOM properties.
另一种方法是使用 removeEventListener()
但我想你已经尝试过这个,但它没有用.这里是问题:
对匿名函数调用 addEventListener
每次都会创建一个新的侦听器.将 removeEventListener
调用到匿名函数无效.匿名函数每次被调用时都会创建一个唯一的对象,尽管它可能会调用一个对象,但它不是对现有对象的引用.以这种方式添加事件侦听器时,请确保它只添加一次,它是永久性的(无法删除),直到它被添加到的对象被销毁.
Calling
addEventListener
to an anonymous function creates a new listener each time. CallingremoveEventListener
to an anonymous function has no effect. An anonymous function creates a unique object each time it is called, it is not a reference to an existing object though it may call one. When adding an event listener in this manner be sure it is added only once, it is permanent (cannot be removed) until the object it was added to, is destroyed.
您实际上是将匿名函数传递给 addEventListener
,因为 eventReturner
返回一个函数.
You are essentially passing an anonymous function to addEventListener
as eventReturner
returns a function.
你有两种可能来解决这个问题:
You have two possibilities to solve this:
不要使用返回函数的函数.直接使用函数:
Don't use a function that returns a function. Use the function directly:
function handler() {
dosomething();
}
div.addEventListener('click',handler,false);
为 addEventListener
创建一个包装器,用于存储对返回函数的引用并创建一些奇怪的 removeAllEvents
函数:
Create a wrapper for addEventListener
that stores a reference to the returned function and create some weird removeAllEvents
function:
var _eventHandlers = {}; // somewhere global
const addListener = (node, event, handler, capture = false) => {
if (!(event in _eventHandlers)) {
_eventHandlers[event] = []
}
// here we track the events and their nodes (note that we cannot
// use node as Object keys, as they'd get coerced into a string
_eventHandlers[event].push({ node: node, handler: handler, capture: capture })
node.addEventListener(event, handler, capture)
}
const removeAllListeners = (targetNode, event) => {
// remove listeners from the matching nodes
_eventHandlers[event]
.filter(({ node }) => node === targetNode)
.forEach(({ node, handler, capture }) => node.removeEventListener(event, handler, capture))
// update _eventHandlers global
_eventHandlers[event] = _eventHandlers[event].filter(
({ node }) => node !== targetNode,
)
}
然后你可以使用它:
addListener(div, 'click', eventReturner(), false)
// and later
removeAllListeners(div, 'click')
注意:如果您的代码运行了很长时间并且您要创建和删除大量元素,则必须确保删除_eventHandlers
当你摧毁它们时.
Note: If your code runs for a long time and you are creating and removing a lot of elements, you would have to make sure to remove the elements contained in _eventHandlers
when you destroy them.
这篇关于Javascript/DOM:如何删除 DOM 对象的所有事件侦听器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!