[英]addEventListener and removeEventListener using forEach
[英]remove an event using removeEventListener before adding an event using addEventListener is not working
我正在嘗試具有允許訂閱任何事件的常規功能。 我想確保每個事件和元素都只訂閱一個。 因此,在添加新的事件偵聽器之前,請刪除之前的事件偵聽器。
問題是,我使之成為上一個事件的方式沒有被刪除,我也不知道為什么。
遵循一個工作示例:
function delegate(el, evt, sel, handler) { let eventListenerHandler = (event) => { var t = event.target; while (t && t !== this) { if (t.matches && t.matches(sel)) { handler.call(t, event); } t = t.parentNode; } } el.removeEventListener(evt, eventListenerHandler, evt === "focus" ? true : false); el.addEventListener(evt, eventListenerHandler, evt === "focus" ? true : false); } let consoleLog = () => console.log("WAS FOCUS"); delegate(document, "focus", "input", consoleLog); delegate(document, "focus", "input", consoleLog);
<input/> <input/>
在示例中可以看到,每次選擇一個輸入時,它都會打印兩次消息“ WAS FOCUS”,而我希望確保只打印一個。
先感謝您。
實現Ry在注釋中建議的一種相對簡單的方法是將處理程序函數存儲在元素本身上-我在這里使用了一個對象,以便可以將不同事件類型的處理程序存儲在事件名稱下。 (您只想為每個元素的一個事件類型使用一個處理程序,對嗎?)
然后,如果已經存在這樣的存儲處理程序,則只需將其刪除, 然后再用新的處理程序覆蓋它即可。
現在,將這樣的數據直接存儲在DOM元素上並不被認為是一種好習慣; 至少是因為可能與將來使用的同名指定屬性發生沖突。 但是在這種情況下,這是解決此問題的非常簡單的方法; 當然,您可以將處理程序函數存儲在其他位置,但是無論如何,您仍然必須保留對DOM元素的引用,因為您還需要能夠區分分配給不同元素的處理程序。
function delegate(el, evt, sel, handler) { el.eventListenerHandler = el.eventListenerHandler || {}; if(el.eventListenerHandler[evt]) { el.removeEventListener(evt, el.eventListenerHandler[evt], evt === "focus" ? true : false); } el.eventListenerHandler[evt] = (event) => { var t = event.target; while (t && t !== this) { if (t.matches && t.matches(sel)) { handler.call(t, event); } t = t.parentNode; } } el.addEventListener(evt, el.eventListenerHandler[evt], evt === "focus" ? true : false); } let consoleLog = () => console.log("WAS FOCUS"); delegate(document, "focus", "input", consoleLog); delegate(document, "focus", "input", consoleLog);
<input/> <input/>
對於removeEventListener(event,functionName)
您必須提供要刪除的功能,該功能先前已添加。
現在在這里,每個delegate(document, "focus", "input", consoleLog);
在自己的作用域上創建函數eventListenerHandler
,並將其添加到addEventListener。
基本上,兩個委托()調用會創建兩個具有相同功能的不同函數eventListenerHandler
。
現在,如果我們可以將先前添加的eventListenerHandler
保存到一個變量中,並稍后在removeEventListener
使用它,則它將起作用。
這是例子。
var temp = function(){}; function delegate(el, evt, sel, handler) { let eventListenerHandler = (event) => { var t = event.target; while (t && t !== this) { if (t.matches && t.matches(sel)) { handler.call(t, event); } t = t.parentNode; } } el.removeEventListener(evt, temp, evt === "focus" ? true : false); el.addEventListener(evt, eventListenerHandler, evt === "focus" ? true : false); temp = eventListenerHandler ; } let consoleLog = () => console.log("WAS FOCUS"); delegate(document, "focus", "input", consoleLog,false); delegate(document, "focus", "input", consoleLog,false);
<input> <input>
為了更好地理解,您可以參考javascript 閉包概念。
對於您的解決方案,您必須將添加為eventListener的每個函數保存為其事件和元素,並在以后使用相同事件對該元素進行調用時刪除該函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.