简体   繁体   English

删除元素时删除 keydown/keyup document.eventListener

[英]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.

相关问题 无法在 document.eventListener 中定义此上下文 - Unable to define this context in document.eventListener 如何用 Jest 测试 document.eventListener - How to test document.eventListener with Jest 打字稿:requestAnimationFrame和eventlistener:keyup / keydown - typescript: requestAnimationFrame and eventlistener:keyup/keydown Javascipt 在使用 setTimeout() 时有效,但在 WordPress 页面上使用 document.eventListener('DOMContentLoaded', x) 时无效。 为什么? - Javascipt works when setTimeout() is used but it isn't working when document.eventListener('DOMContentLoaded', x) is used on WordPress page. Why? EventListener keydown正在工作,但keyup不起作用 - EventListener keydown is working but keyup isn't JavaScript EventListener 一键触发keyup后多次keydown停止 - JavaScript EventListener multiple keydown stops after one key triggers keyup 专注于元素,然后导致keydown或keyup空间事件 - focus on element and then cause a keydown or keyup space event 按下和按下键时Javascript图像发生变化 - Javascript image change when keydown and keyup 输入时按下和按下时显示Popover - Show Popover when keydown and keyup on input 按下键盘提示时无法触发键盘提示 - Keyup not firing when keydown opens an alert
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM