[英]Can't remove all event listeners
我正在嘗試從某個網站上刪除事件偵聽器,但沒有成功。
有一個 javascript 腳本可以創建這些事件:
document.addEventListener('contextmenu', function (ev) {
ev.preventDefault();
}
)
我試圖用以下方法刪除它:
document.removeEventListener('contextmenu', function (ev) {
ev.preventDefault();
})
我也試過:
(getEventListeners(document)).contextmenu = null
但它沒有用,我想是因為我使用了一個不同的新功能。
有沒有辦法清除所有事件?
參考:
無法刪除事件偵聽器
您需要指定綁定到removeEventListener
的函數
您可以通過創建一個函數並傳遞對addEventListener
和removeEventListener
的引用來做到這一點。
// create a function function onRightClick(ev) { ev.preventDefault(); console.log('onRightClick') } // pass the function to both add and remove document.addEventListener('contextmenu', onRightClick) document.removeEventListener('contextmenu', onRightClick)
這是一個完整的示例,它將所有事件緩存到元素中,允許您刪除特定事件,所有事件類型的所有事件。
它還有一個 MutationObserver 觀察 DOM 的變化,如果一個元素被移除,那么附加到它的事件也會被移除。
const Events = (() => { const cache = new Map const observer = new MutationObserver(function(mutations) { for (let mutation of mutations) { if (mutation.type === 'childList') { if (mutation.removedNodes.length) { console.log('element removed from the dom, removing all events for the element') mutation.removedNodes.forEach(x => Events.remove(x)) } } } }) // watch the dom for the element being deleted observer.observe(document.body, { childList: true }) return { add(el, type, fn, capture = false) { let cached = cache.get(el) if (!cached) { cached = {} cache.set(el, cached) } if (!cached[type]) { cached[type] = new Set } cached[type].add(fn) el.addEventListener(type, fn, capture) }, remove(el, type, fn) { const cached = cache.get(el) if (!cached) { return false } // remove all events for an event type if (type && !fn) { cached[type].forEach(fn => { el.removeEventListener(type, fn) }) cached[type] = new Set } // remove a specific event else if (type && fn) { el.removeEventListener(type, fn) // remove the event from the cache cached[type].delete(fn) } // remove all events for the element else { for (key in cached) { cached[key].forEach(fn => { el.removeEventListener(key, fn) }) } cache.delete(el) } }, show(el, type) { const cached = cache.get(el) if (!cached) { return false } if (type) { return cached[type] } return cached } } })() function onRightClick() {} Events.add(document, 'contextmenu', onRightClick) Events.remove(document, 'contextmenu', onRightClick) // remove a specific event callback Events.remove(document, 'contextmenu') // remove specific event types from an element Events.remove(document) // remove all events from an element const testElement = document.querySelector('#test_element') Events.add(testElement, 'click', function deleteSelf(e) { this.parentNode.removeChild(this) })
<div id="test_element"> when you <strong>click me</strong> I will be deleted from the DOM which will fire the MutationObserver to remove all my events </div>
您可以嘗試克隆已添加所有偵聽器的元素並將其添加回其父元素。 使用cloning
,您會丟失所有附加到元素的偵聽器。 試試這個,
var element = document.getElementById('myElement'),
clone = el.cloneNode(true);
element.parentNode.replaceChild(clone, element);
但是,這不適用於全局事件偵聽器,或者只是直接在文檔而不是元素上設置的事件偵聽器,因為文檔是層次結構的根(不能有 parentNode)
要擺脫未知的事件偵聽器,您可以clone
元素,然后將原始內容移動到克隆的內容中,然后用克隆替換原始內容。
如果您不關心包含元素的事件偵聽器,您還可以使用.clone(true)
(或false
,不記得了)深度克隆原始.clone(true)
。 這樣您就不必移動內容了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.