JS函数设置太多addEventListeners

问题描述 投票:0回答:3

我有一个具有搜索功能的单页应用程序(SPA),在这里我试图跟踪用户如何与Adobe Analytics中的搜索栏进行交互。如果我导航到SPA的5个不同“页面”,则以下代码将触发该事件6次。似乎已设置addEventListener,但如果在“页面”上没有搜索发生,则不会清除。每次加载“页面”时,这些事件侦听器实际上都会排队,并且一旦输入搜索,它们都将同时触发,从而清除队列。

如果不执行搜索,如何清除事件监听器,并且仅在通过按Enter执行搜索后才触发此事件?

假设我有代码:

clearInterval(interval);
var interval = setInterval(function(){
    if (document.querySelector("form div[data-autoid='search_bar'] input")) {       
        inputField = document.querySelector("form div[data-autoid='search_bar'] input")
        inputField.addEventListener('keydown', searchEntered)
        clearInterval(interval);
    } 
}, 500);

function searchEntered(e) {
    if (e.key == "Enter") {
      console.log("search entered");
      var event = new CustomEvent('searchEntered');
     dispatchEvent(event);
    }
}
javascript html javascript-events addeventlistener event-listener
3个回答
1
投票

如果要删除现有的事件侦听器,请使用EventTarget.removeEventListener()

作为MDN page状态,您需要指定传递给type的相同listeneraddEventListener()参数。如果还传递了选项,则还应该将相同的传递给removeEventListener()

鉴于先前通过调用addEventListener()添加了一个事件侦听器,最终您可能会需要删除它。显然,您需要为removeEventListener()指定相同的类型和侦听器参数,但是选项或useCapture参数呢?

虽然addEventListener()将让您为相同类型的同一个侦听器添加多次(如果选项不同),则唯一的removeEventListener()检查的选项是capture / useCapture标志。它的值必须匹配,removeEventListener()才能匹配,但其他值不匹配。

注意,不可能将多个相同的侦听器添加到同一元素。从MDN page

如果在相同的EventTarget上使用相同的参数注册了多个相同的EventListener,则将丢弃重复的实例。它们不会导致两次调用EventListener,也不需要使用removeEventListener()方法手动将其删除。


0
投票

如果您[将事件侦听器添加到窗口] >>一旦发生,它将捕获页面(委托目标)上的所有按键事件,请检查该事件是否由Enter键触发,以及是否parentNode具有属性data-autoid ='search_bar'。如果为true,则调度您的自定义事件。

即使DOM更改,它也将继续起作用

addEventListener('keydown', e => {
  if (e.key == 'Enter' && e.target.parentNode.dataset.autoid == 'search_bar') {
    console.log('search entered');
    const event = new CustomEvent('searchEntered');
    dispatchEvent(event);
  }
})
<div data-autoid='search_bar'> 
  Will trigger <input />
</div>

<label>
  Won't trigger <input />
</label>

0
投票
var interval = setInterval(function(){
  var inputField = document.querySelector("form div[data-autoid='search_bar'] input");
  if (inputField && !inputField.dataset.searchEventAttached) {
    inputField.addEventListener('keydown', searchEntered);
    inputField.dataset.searchEventAttached = true;
  } 
  clearInterval(interval);
}, 500);
© www.soinside.com 2019 - 2024. All rights reserved.