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

只是问题:有什么办法可以彻底删除一个对象的所有事件,例如一个div?

编辑:我添加每div.addEventListener('click',eventReturner(),false); 一个事件。

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

编辑2:我find了一种方法,这是工作,但不可能用于我的情况:

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

我不确定你的意思是删除所有事件 。 为特定types的事件或一个types的所有事件处理程序删除所有处理程序?

删除所有事件处理程序

如果你想删除所有的事件处理器(任何types的),你可以克隆这个元素并用它的clone来代替它:

 var clone = element.cloneNode(); while (element.firstChild) { clone.appendChild(element.lastChild); } element.parentNode.replaceChild(clone, element); 

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


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

另一种方法是使用removeEventListener()但我想你已经试过这个,它不工作。 这里有一个问题 :

调用addEventListener到一个匿名函数会每次创build一个新的监听器。 调用removeEventListener到一个匿名函数没有任何作用 。 匿名函数在每次被调用的时候创build一个唯一的对象,虽然它可能会调用一个对象,但它不是对现有对象的引用。 当以这种方式添加事件侦听器时,确保只添加一次,它是永久的(不能被删除),直到被添加到的对象被销毁。

eventReturner是通过一个匿名函数addEventListener作为eventReturner返回一个函数。

你必须想办法解决这个问题:

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

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

     var _eventHandlers = {}; // somewhere global function addListener(node, event, handler, capture) { if(!(node in _eventHandlers)) { // _eventHandlers stores references to nodes _eventHandlers[node] = {}; } if(!(event in _eventHandlers[node])) { // each entry contains another entry for each event type _eventHandlers[node][event] = []; } // capture reference _eventHandlers[node][event].push([handler, capture]); node.addEventListener(event, handler, capture); } function removeAllListeners(node, event) { if(node in _eventHandlers) { var handlers = _eventHandlers[node]; if(event in handlers) { var eventHandlers = handlers[event]; for(var i = eventHandlers.length; i--;) { var handler = eventHandlers[i]; node.removeEventListener(event, handler[0], handler[1]); } } } } 

    然后你可以使用它:

     addListener(div, 'click', eventReturner(), false) // and later removeListeners(div, 'click') 

DEMO

注意:如果你的代码运行了很长时间,而且你正在创build和删除很多元素,那么当你销毁它们时,你必须确保删除_eventHandlers包含的元素。

使用事件监听器自己的函数remove() 。 例如:

 getEventListeners().click.forEach((e)=>{e.remove()}) 

这将删除所有来自儿童的听众,但是对于大页面来说会很慢。 残酷地写简单。

 element.outerHTML = element.outerHTML; 

正如corwin.amber所说,Webkit和其他的有所不同。

在Chrome中:

 getEventListeners(document); 

哪一个给你一个对象与所有现有的事件监听器:

 Object click: Array[1] closePopups: Array[1] keyup: Array[1] mouseout: Array[1] mouseover: Array[1] ... 

从这里你可以到达你想要删除的监听器:

 getEventListeners(document).copy[0].remove(); 

所以所有的事件监听器:

 for(var eventType in getEventListeners(document)) { getEventListeners(document)[eventType].forEach( function(o) { o.remove(); } ) } 

在Firefox中

有点不同,因为它使用不包含remove函数的侦听器包装器。 你必须得到你想要删除的侦听器:

 document.removeEventListener("copy", getEventListeners(document).copy[0].listener) 

所有事件监听器:

 for(var eventType in getEventListeners(document)) { getEventListeners(document)[eventType].forEach( function(o) { document.removeEventListener(eventType, o.listener) } ) } 

我偶然发现这个post试图禁用恼人的新闻网站的复制保护。

请享用!

 var div = getElementsByTagName('div')[0]; /* first div found; you can use getElementById for more specific element */ div.onclick = null; // OR: div.onclick = function(){}; 

//编辑

我不知道你用什么方法来附加事件。 对于addEventListener你可以使用这个:

 div.removeEventListener('click',functionName,false); // functionName is the name of your callback function 

更多 细节

可能是浏览器会为你做,如果你做这样的事情:

复制div及其属性,并将其插入旧的,然后将内容从旧到新,并删除旧的?

删除document所有事件

一个class轮:

 for (key in getEventListeners(document)) { getEventListeners(document)[key].forEach(function(c) { c.remove() }) } 

漂亮的版本:

 for (key in getEventListeners(document)) { getEventListeners(document)[key].forEach(function(c) { c.remove() }) }