我不确定你的意思是什么,是要删除某种类型的所有事件处理程序还是删除一种类型的所有事件处理程序?
删除所有事件处理程序
如果您想删除所有事件处理程序(任何类型的),可以使用clone节点并用其副本替换它:
var clone = element.cloneNode(true)
注意: 这将保留属性和子节点,但不会保留对DOM属性的任何更改。
移除特定类型的“匿名”事件处理程序
另一种方法是使用removeEventListener()
,但我猜你已经尝试过了,但没有生效。 这里有个问题:
调用addEventListener
并传入一个匿名函数,每次都会创建一个新的监听器。调用removeEventListener
并传入一个匿名函数没有效果。每次调用匿名函数都会创建一个唯一的对象,它不是对现有对象的引用,但可能调用一个对象。以这种方式添加事件侦听器时,确保仅添加一次,并且在被添加到的对象被销毁之前,它是永久性的(无法删除)。
实际上,你将一个返回函数的函数传递给了addEventListener
作为eventReturner
。
你有两种可能解决方法:
不要使用返回函数的函数。直接使用该函数:
function handler() {
dosomething();
}
div.addEventListener('click',handler,false);
创建一个包装器,用于存储返回函数的引用,并创建一些奇怪的removeAllEvents
函数: 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)
removeAllListeners(div, 'click')
演示
注意: 如果你的代码运行时间很长,而且你创建和删除了很多元素,你必须确保在销毁它们时删除_eventHandlers
中包含的元素。
div.onclick=null
进行移除。当然,在这种情况下,您不应该使用addEventListener
,因为它会添加一个不同于onclick
中的监听器。 - venimus