Flo*_*ler 73 javascript events dom
只是提问:有没有办法彻底删除对象的所有事件,例如div?
编辑:我正在添加div.addEventListener('click',eventReturner(),false);
一个事件.
function eventReturner() {
return function() {
dosomething();
};
}
Run Code Online (Sandbox Code Playgroud)
EDIT2:我找到了一种方法,但是不能用于我的情况:
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);
}
Run Code Online (Sandbox Code Playgroud)
Fel*_*ing 88
我不确定你删除所有事件的意思.删除特定类型事件的所有处理程序或一种类型的所有事件处理程序?
如果要删除所有事件处理程序(任何类型),可以克隆该元素并将其替换为其克隆:
var clone = element.cloneNode(true);
Run Code Online (Sandbox Code Playgroud)
注意:这将保留属性和子项,但不会保留对DOM属性的任何更改.
另一种方法是使用,removeEventListener()
但我想你已经尝试过这个并没有用.这是一个问题:
调用
addEventListener
匿名函数每次都会创建一个新的侦听器.调用removeEventListener
匿名函数无效.匿名函数每次调用时都会创建一个唯一的对象,它不是对现有对象的引用,尽管它可以调用一个对象.以这种方式添加事件侦听器时,请确保它只添加一次,它是永久的(无法删除),直到它被添加到的对象被销毁.
您实际上是将一个匿名函数传递给addEventListener
as eventReturner
返回一个函数.
你必须有可能解决这个问题:
不要使用返回函数的函数.直接使用该功能:
function handler() {
dosomething();
}
div.addEventListener('click',handler,false);
Run Code Online (Sandbox Code Playgroud)创建一个包装器,用于addEventListener
存储对返回函数的引用并创建一些奇怪的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]);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以用它:
addListener(div, 'click', eventReturner(), false)
// and later
removeListeners(div, 'click')
Run Code Online (Sandbox Code Playgroud)注意:如果您的代码运行了很长时间并且您正在创建并删除大量元素,则必须确保在_eventHandlers
销毁它们时删除包含的元素.
小智 25
使用事件监听器自己的功能remove()
.例如:
getEventListeners().click.forEach((e)=>{e.remove()})
Run Code Online (Sandbox Code Playgroud)
pab*_*mbs 24
这将从子节点中删除所有侦听器,但对于大页面来说会很慢.写得非常简单.
element.outerHTML = element.outerHTML;
Run Code Online (Sandbox Code Playgroud)
Ada*_*atz 10
克隆该元素并用其克隆替换该元素。事件不会被克隆。
\nelem.replaceWith(elem.cloneNode(true));\n
Run Code Online (Sandbox Code Playgroud)\n这使用Node.cloneNode()来克隆elem
DOM 对象,该对象会忽略所有事件处理程序(不过,正如Jan Turo\xc5\x88\ 的回答所述,类似的属性onclick="\xe2\x80\xa6"
将保留)。然后它使用Element.replaceWith()替换elem
该克隆。简单地分配给匿名克隆对我来说不起作用。
elem.outerHTML
这应该比重新定义自身更快更干净(如pabombs的答案所建议的),但可能比迭代并清除每个侦听器的答案慢(注意这getEventListeners()
似乎只在Chrome的开发控制台\xe2\x80中可用) \x94在 Chrome 的其他地方没有,在 Firefox 上根本没有)。据推测,在需要清除的听众数量较大时,这种非循环解决方案会变得更快。
(这是在asheroto 的评论的帮助下对Felix Kling 的答案的简化。)
\n正如corwin.amber所说,Webkit和其他人之间存在差异.
在Chrome中:
getEventListeners(document);
Run Code Online (Sandbox Code Playgroud)
这为您提供了一个包含所有现有事件监听器的对象:
Object
click: Array[1]
closePopups: Array[1]
keyup: Array[1]
mouseout: Array[1]
mouseover: Array[1]
...
Run Code Online (Sandbox Code Playgroud)
在这里,您可以访问要删除的侦听器:
getEventListeners(document).copy[0].remove();
Run Code Online (Sandbox Code Playgroud)
所以所有的事件监听器:
for(var eventType in getEventListeners(document)) {
getEventListeners(document)[eventType].forEach(
function(o) { o.remove(); }
)
}
Run Code Online (Sandbox Code Playgroud)
在Firefox中
有点不同,因为它使用不包含删除函数的侦听器包装器.您必须获取要删除的侦听器:
document.removeEventListener("copy", getEventListeners(document).copy[0].listener)
Run Code Online (Sandbox Code Playgroud)
所有事件监听器:
for(var eventType in getEventListeners(document)) {
getEventListeners(document)[eventType].forEach(
function(o) { document.removeEventListener(eventType, o.listener) }
)
}
Run Code Online (Sandbox Code Playgroud)
我偶然发现这篇文章试图禁用新闻网站的烦人复制保护.
请享用!
您可以添加一个钩子函数来拦截所有对addEventHandler
. 该钩子会将处理程序推送到可用于清理的列表。例如,
if (EventTarget.prototype.original_addEventListener == null) {
EventTarget.prototype.original_addEventListener = EventTarget.prototype.addEventListener;
function addEventListener_hook(typ, fn, opt) {
console.log('--- add event listener',this.nodeName,typ);
this.all_handlers = this.all_handlers || [];
this.all_handlers.push({typ,fn,opt});
this.original_addEventListener(typ, fn, opt);
}
EventTarget.prototype.addEventListener = addEventListener_hook;
}
Run Code Online (Sandbox Code Playgroud)
您应该将此代码插入到主网页顶部附近(例如index.html
)。在清理期间,您可以循环遍历 all_handlers,并为每个处理程序调用removeEventHandler。不必担心使用同一函数多次调用removeEventHandler。它是无害的。
例如,
function cleanup(elem) {
for (let t in elem) if (t.startsWith('on') && elem[t] != null) {
elem[t] = null;
console.log('cleanup removed listener from '+elem.nodeName,t);
}
for (let t of elem.all_handlers || []) {
elem.removeEventListener(t.typ, t.fn, t.opt);
console.log('cleanup removed listener from '+elem.nodeName,t.typ);
}
}
Run Code Online (Sandbox Code Playgroud)
注意:对于 IE,请使用 Element 而不是 EventTarget,并将 => 更改为 function 以及其他各种内容。
您可以添加功能并通过分配它们来删除所有其他点击
btn1 = document.querySelector(".btn-1")
btn1.addEventListener("click" , _=>{console.log("hello")})
btn1.addEventListener("click" , _=>{console.log("How Are you ?")})
btn2 = document.querySelector(".btn-2")
btn2.onclick = _=>{console.log("Hello")}
btn2.onclick = _=>{console.log("Bye")}
Run Code Online (Sandbox Code Playgroud)
<button class="btn-1">Hello to Me</button>
<button class="btn-2">Hello to Bye</button>
Run Code Online (Sandbox Code Playgroud)