AddEventListener is fired several times for the same descriptor when passing arguments with an anonymous function

For some reason, an event listener is fired twice for each element when passing arguments to an anonymous function. For example, the click event on the el element will be logged once and thus will fire once.

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

But if I want to pass my own arguments, it will register and run twice.

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

The question is why and what is the solution?

I looked elsewhere and cannot find a solution or understand why this problem arises. I tried to implement the solutions in How to pass an argument to the listener function passed to addEventListener? but they didnโ€™t help -

I made a basic anonymous function or closure, and then a more advanced version, shown below, but it really worked.

I donโ€™t understand why passing arguments does not cause the element event to be registered once and passes the arguments, causing the element event to be registered twice.

Here is the code:

 <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> 

Any help would be greatly appreciated. Thanks.

+5
source share
3 answers

The simplest solution is to create a new handler only once:

 var newHandle = function(event) { handle(event, myArgument); }; el.addEventListener("click", newHandle, false); el.addEventListener("click", newHandle, false); 
+14
source

Well,

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

Registers the same function "handle ()"

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

Registers "function () {handle (event, myArgument)" ... which are two unique anonymous functions. Thus, it fires twice.

Although I donโ€™t quite understand why you would like to register it twice, the solution would be to create a function that returns your function that takes parameters.

 el.addEventListener("click", crateHandle(myArgument), false); var createHandle = function(myArgument) { return function(event) { .... do something }; } 

He still does not solve the problem of fire twice.

+2
source

addEventListener registers as many listeners as it uses.

According to the documentation, it takes 3 arguments, the third - useCapture , which has nothing to do with registering a listener twice or not. By default, it is set to false , so adding false as the third parameter changes little.

0
source

Source: https://habr.com/ru/post/1203810/


All Articles