一些第三方插件会将eventListener
附加到网站中。如何在不知道附加的函数的情况下删除eventListener
。
我参考了removeEventListener,但是我无法得到删除它的线索。
例如:getEventListeners(window)
显示已附加的事件。但是,如果我尝试使用window.removeEventListener("eventname")
来删除事件,除非我知道该函数,否则它无法正常工作。
请帮忙解答,提前感谢。
一些第三方插件会将eventListener
附加到网站中。如何在不知道附加的函数的情况下删除eventListener
。
我参考了removeEventListener,但是我无法得到删除它的线索。
例如:getEventListeners(window)
显示已附加的事件。但是,如果我尝试使用window.removeEventListener("eventname")
来删除事件,除非我知道该函数,否则它无法正常工作。
请帮忙解答,提前感谢。
getEventListeners(window)
将返回一个包含事件及其已注册事件监听器的映射表。
例如,对于 DOMContentLoaded
事件,您可以有多个事件监听器。如果您知道要删除的监听器的索引(或仅存在一个),则可以执行以下操作:
var eventlistener = getEventListeners(window)["DOMContentLoaded"][index];
window.removeEventListener("DOMContentLoaded",
eventlistener.listener,
eventlistener.useCapture);
remove
:getEventListeners(window).DOMContentLoaded[0].remove()
。 - dfsq很遗憾,您不能这样做。您需要有事件处理程序函数的引用才能通过 removeEventListener
来移除它。
如果您无法获得该引用,则唯一的选择是完全替换该 Node
。
addEventListener
添加的本地事件不会存储在JavaScript可访问的任何位置。 - jAndygetEventListeners
是可以实现的,因为它存储着事件监听函数。 - dfsqgetEventListeners
,仅适用于Chrome和Edge浏览器。// selector is optional - defaults to all elements including window and document
// Do not pass window / document objects. Instead use pseudoselectors: 'window' or 'document'
// eTypeArray is optional - defaults to clearing all event types
function removeAllEventListeners(selector = '*', eTypeArray = ['*']) {
switch (selector.toLowerCase()) {
case 'window':
removeListenersFromElem(window);
break;
case 'document':
removeListenersFromElem(document);
break;
case '*':
removeListenersFromElem(window);
removeListenersFromElem(document);
default:
document.querySelectorAll(selector).forEach(removeListenersFromElem);
}
function removeListenersFromElem(elem) {
let eListeners = getEventListeners(elem);
let eTypes = Object.keys(eListeners);
for (let eType of inBoth(eTypes, eTypeArray)) {
eListeners[eType].forEach((eListener)=>{
let options = {};
inBoth(Object.keys(eListener), ['capture', 'once', 'passive', 'signal'])
.forEach((key)=>{ options[key] = eListener[key] });
elem.removeEventListener(eType, eListener.listener, eListener.useCapture);
elem.removeEventListener(eType, eListener.listener, options);
});
}
}
function inBoth(arrA, arrB) {
setB = new Set(arrB);
if (setB.has('*')) {
return arrA;
} else {
return arrA.filter(a => setB.has(a));
}
}
}
使用:
removeAllEventListeners('a.fancyLink'); // remove all event types
removeAllEventListeners('a.fancyLink', ['click', 'hover']); // remove these types
removeAllEventListeners('*', ['click', 'hover']); // remove these types everywhere
removeAllEventListeners(); // remove everything you can
removeEventListener()
时,最好使用与调用addEventListener()
时相同的值。options
的使用尝试通过希望使用添加监听器时相同的值来处理这个问题,从而调用removeEventListener
。更新:2023年
在现代浏览器中,可以在不知道实际函数引用的情况下删除EventListeners。
使用
AbortController
来移除事件。使用AbortSignal,您可以简单地获取信号来为您删除它:
示例代码:
const controller = new AbortController();
const { signal } = controller;
window.addEventListener('resize', () => doSomething(), { signal });
controller.abort(); // It wll remove the "resize" event handler.