簡體   English   中英

addEventListener 在使用匿名 function 傳入 arguments 時為同一個句柄觸發多次

[英]addEventListener firing multiple times for the same handle when passing in arguments with anonymous function

出於某種原因,當將 arguments 傳遞給匿名 function 時,事件偵聽器會為每個元素觸發兩次。 即,元素el上的點擊事件將注冊一次,因此觸發一次。

el.addEventListener("click", handle, false);
el.addEventListener("click", handle, false);

但如果我想將自己的 arguments 傳遞給它,它會注冊並觸發兩次。

el.addEventListener("click", function() { handle(event, myArgument); }, false);
el.addEventListener("click", function() { handle(event, myArgument); }, false);

問題是為什么以及解決方案是什么?

我在別處看了看,似乎找不到解決方案或理解為什么會出現這個問題。 我嘗試實現如何將參數傳遞給在 addEventListener 中傳遞的監聽器 function 中的解決方案? 但他們沒有幫助——

我做了基本的匿名 function 或閉包,然后是更高級的版本,如下所示,但它確實有效。

我不明白為什么不傳遞 arguments 會導致元素事件注冊一次,而傳遞 arguments 會導致元素事件注冊兩次。

這是代碼:

<html>
    <head>
        <script type="text/javascript">
            var handle_2 = function(evt, type) {
                var test;
                switch (type) {
                    case "focus": 
                        console.log(evt.target.value);
                        break;
                    case "click":
                        console.log(evt.target.id + " was clicked");
                        break;
                    default: console.log("no type found");
                }
            };
        
            window.onload = function() {
                var textbox = document.getElementById("t1");
                var button = document.getElementById("btn");
                textbox.value = "456";
                button.value = "Press";

                var typeFocus = "focus", typeClick = "click";

                textbox.addEventListener("focus", (function(typeFocus) { return function(evt) { handle_2(evt, typeFocus); }})(typeFocus), false);
                button.addEventListener("click", (function(typeClick) { return function(evt) { handle_2(evt, typeClick); }})(typeClick), false);
                
                // Registers again for each element. Why?
                textbox.addEventListener("focus", (function(typeFocus) { return function(evt) { handle_2(evt, typeFocus); }})(typeFocus), false);
                button.addEventListener("click", (function(typeClick) { return function(evt) { handle_2(evt, typeClick); }})(typeClick), false);
            };
        </script>
    </head>
    <body>
        <div id="wrapper">
            <input id="t1" type="text" />
            <input id="btn" type="button" />
        </div>
    </body>
</html>

任何幫助,將不勝感激。

最簡單的解決方案是只創建一次新的處理程序:

var newHandle = function(event) { handle(event, myArgument); };

el.addEventListener("click", newHandle, false);
el.addEventListener("click", newHandle, false);

好,,

el.addEventListener("click", handle, false);
el.addEventListener("click", handle, false);

注冊到相同的函數“handle()”

el.addEventListener("click", function() { handle(event, myArgument); }, false);
el.addEventListener("click", function() { handle(event, myArgument); }, false);

注冊“function() { handle(event, myArgument)”...這是兩個獨特的匿名函數。 因此它會觸發兩次。

雖然我不完全理解您為什么要注冊它兩次,但解決方案是創建一個函數,返回帶參數的函數。

el.addEventListener("click", crateHandle(myArgument), false);

var createHandle = function(myArgument) {
  return function(event) {
    .... do something
  };
}

盡管如此,它仍然沒有解決火災兩次問題。

addEventListener注冊盡可能多的監聽器。

根據文檔,它需要 3 個參數,第三個參數是useCapture ,它與是否注冊監聽器兩次無關。 它默認設置為false ,因此添加false作為第三個參數不會有太大變化。

 useEffect(()=>{
        document.addEventListener('keydown', someFunction); 
    }, []);

使用 useEffect 鈎子,最后的空數組將直到加載后不刷新組件

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM