[英]Remove keydown/keyup document.eventListener when element is deleted
I have a div with id "div1" that gets updated when the user presses keys.我有一个 ID 为“div1”的 div,当用户按键时它会更新。 I have added an eventlistener for the keydown event that runs a function "update" and attached it to the document as follows:我为运行 function“更新”的 keydown 事件添加了一个事件监听器,并将其附加到文档中,如下所示:
let div=document.getElementById("div1");
document.addEventListener("keydown",update);
div.remove()
//event listener remains listening, because it's attached to document
When "div1" is removed from the DOM, the event listener remains.当“div1”从 DOM 中移除时,事件侦听器仍然存在。 If I added the event listener to "div1", then the event listener would be removed when div1 is removed from the DOM.如果我将事件侦听器添加到“div1”,那么当从 DOM 中删除 div1 时,事件侦听器将被删除。
let div=document.getElementById("div1");
div.addEventListener("keydown",update);
div.remove()
//event listener removed, no more listening
This approach doesn't work however, since the element has to be focused for the keydown event to trigger and my div1 doesn't have focus and I want the user to be able to update without clicking on the item anyway.但是,这种方法不起作用,因为元素必须聚焦才能触发 keydown 事件,而我的 div1 没有焦点,我希望用户能够在不单击该项目的情况下进行更新。
Is there a way to automatically remove the event listener when the element is deleted (as in case 2) even though the event listener is attached to the document (as in case 1).有没有一种方法可以在删除元素时自动删除事件侦听器(如案例 2),即使事件侦听器已附加到文档(如案例 1)。 Alternatively, is there another alternative for attaching the event listener to the element and still listening for all keydown events.或者,是否有另一种方法可以将事件侦听器附加到元素并仍然侦听所有按键事件。
Here is a slightly more passive way than using the MutationObserver (element will only be removed the first time the event is fired after removal, rather than when the element is removed):这是一种比使用 MutationObserver 稍微更被动的方法(元素只会在删除后第一次触发事件时删除,而不是在删除元素时删除):
document.addEventListener("keydown",update);
function update(){
let div=document.getElementById("div1");
if(div===null || div.isConnected===false){//div1 is currently not attached to DOM
document.removeEventListener("keydown",update);
return;
}
//other update code here
}
You can use event delegation.您可以使用事件委托。 Then you can check the event target in the callback to see if it matches the removed element so you can unbind the event listener.然后你可以检查回调中的事件目标,看它是否与删除的元素匹配,这样你就可以解除事件监听器的绑定。
let parent = document.getElementById("parent");
parent.addEventListener("keydown", function(event) {
let target = event.target;
if (target.id === "div1") {
update();
parent.removeEventListener("keydown", arguments.callee);
}
});
You can remove that event listener with a MutationObserver
observing changes to div1
's parent element and looking to see if div1
was removed by the change:您可以使用MutationObserver
观察对div1
的父元素的更改并查看div1
是否因更改而被删除:
let div1 = document.getElementById("div1"); // Add the handler let handler = (event) => { console.log(`key pressed: ${event.key}`); }; document.addEventListener("keydown", handler); // Watch for changes to the parent of the div const observer = new MutationObserver((mutationList) => { // If `div1` is done, remove the event handler and // stop listening for changes. // You could use `mutationList` here if you liked rather than // doing getElementById if (.document.getElementById("div1")) { console,log("div1 is gone; removing handler and mutation observer"); div = null, // Not necessary. but probably good document,removeEventListener("keydown"; handler). observer;disconnect(); handler = null, // Not necessary; but probably good } }). observer.observe(div1,parentElement: { childList, true: subtree; true }). // Just a way to remove the div document.querySelector("input[value='Remove div1']"),addEventListener("click". () => { div1;remove(); div1 = null; });
<div id="div1">This is div1</div> <input type="button" value="Remove div1">
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.