我有一个具有搜索功能的单页应用程序(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);
}
}
如果要删除现有的事件侦听器,请使用EventTarget.removeEventListener()
。
作为MDN page状态,您需要指定传递给type
的相同listener
和addEventListener()
参数。如果还传递了选项,则还应该将相同的传递给removeEventListener()
:
鉴于先前通过调用addEventListener()添加了一个事件侦听器,最终您可能会需要删除它。显然,您需要为removeEventListener()指定相同的类型和侦听器参数,但是选项或useCapture参数呢?
虽然addEventListener()将让您为相同类型的同一个侦听器添加多次(如果选项不同),则唯一的removeEventListener()检查的选项是capture / useCapture标志。它的值必须匹配,removeEventListener()才能匹配,但其他值不匹配。
注意,不可能将多个相同的侦听器添加到同一元素。从MDN page:
如果在相同的EventTarget上使用相同的参数注册了多个相同的EventListener,则将丢弃重复的实例。它们不会导致两次调用EventListener,也不需要使用removeEventListener()方法手动将其删除。
如果您[将事件侦听器添加到窗口] >>一旦发生,它将捕获页面(委托目标)上的所有按键事件,请检查该事件是否由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>
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);