Javascript/DOM:如何删除 DOM 对象的所有事件侦听器?

2022-08-30 04:32:20

只是问题:有没有办法完全删除对象的所有事件,例如div?

编辑:我正在按事件添加。div.addEventListener('click',eventReturner(),false);

function eventReturner() {
    return function() {
        dosomething();
    };
}

编辑2:我找到了一种方法,这是有效的,但不可能用于我的情况:

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);
}

答案 1

我不确定您删除所有事件是什么意思。删除特定类型的事件的所有处理程序还是一种类型的所有事件处理程序?

删除所有事件处理程序

如果要删除所有事件处理程序(任何类型),可以克隆该元素并将其替换为其克隆:

var clone = element.cloneNode(true);

注意:这将保留属性和子级,但不会保留对 DOM 属性的任何更改。


删除特定类型的“匿名”事件处理程序

另一种方法是使用demoveEventListener(),但我想你已经尝试过了,但它不起作用。这是陷阱

调用匿名函数每次都会创建一个新的侦听器。调用匿名函数不起作用。匿名函数每次调用时都会创建一个唯一的对象,它不是对现有对象的引用,尽管它可以调用一个对象。以这种方式添加事件侦听器时,请确保它只添加一次,它是永久性的(无法删除),直到它被添加到的对象被销毁。addEventListenerremoveEventListener

您实际上是在将一个匿名函数传递给返回一个函数。addEventListenereventReturner

您有两种可能性来解决这个问题:

  1. 不要使用返回函数的函数。直接使用该函数:

     function handler() {
         dosomething();
     }
    
     div.addEventListener('click',handler,false);
    
  2. 为它创建一个包装器,用于存储对返回函数的引用,并创建一些奇怪的函数:addEventListenerremoveAllEvents

     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


答案 2

这将删除儿童的所有侦听器,但对于大页面来说会很慢。写起来非常简单。

element.outerHTML = element.outerHTML;