Javascript 使用匿名函数传入参数时,addEventListener 为同一个句柄多次触发
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26146108/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
addEventListener firing multiple times for the same handle when passing in arguments with anonymous function
提问by user717236
For some reason, the event listener is firing twice for each element when passing arguments into an anonymous function. I.e., the click event on element elwill register once and, thus, fire once.
出于某种原因,当将参数传递给匿名函数时,事件侦听器会为每个元素触发两次。即,元素上的点击事件el将注册一次,因此触发一次。
el.addEventListener("click", handle, false);
el.addEventListener("click", handle, false);
But if I want to pass my own arguments to it, it will register and fire twice.
但是如果我想将我自己的参数传递给它,它会注册并触发两次。
el.addEventListener("click", function() { handle(event, myArgument); }, false);
el.addEventListener("click", function() { handle(event, myArgument); }, false);
The question is why and what's the solution?
问题是为什么以及解决方案是什么?
I looked elsewhere and cannot seem to find a solution or understand why this problem is occurring. I tried implementing the solutions in How to pass an argument to the listener function passed in addEventListener?but they did not help --
我查看了其他地方,似乎无法找到解决方案或理解为什么会出现此问题。我尝试实现如何将参数传递给 addEventListener 中传递的侦听器函数中的解决方案?但他们没有帮助——
I did the basic anonymous function or closure and then the more advanced version, which is the shown below but it did work.
我做了基本的匿名函数或闭包,然后是更高级的版本,如下所示,但它确实有效。
I don't get why passing no arguments causes the element event to register once and passing arguments causing the element event to register 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 appreciated. Thank you.
任何帮助,将不胜感激。谢谢你。
回答by Felix Kling
The simplest solution is to create the new handler only once:
最简单的解决方案是只创建一次新的处理程序:
var newHandle = function(event) { handle(event, myArgument); };
el.addEventListener("click", newHandle, false);
el.addEventListener("click", newHandle, false);
回答by Stefan Svebeck
Well,,
好,,
el.addEventListener("click", handle, false);
el.addEventListener("click", handle, false);
Registers to the same function "handle()"
注册到相同的函数“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 will fire twice.
注册“function() { handle(event, myArgument)”...这是两个独特的匿名函数。因此它会触发两次。
Although I don't fully understand why you would want to register it twice, the solution would be to create a function returning your function that takes parameters.
虽然我不完全理解您为什么要注册它两次,但解决方案是创建一个函数,返回带参数的函数。
el.addEventListener("click", crateHandle(myArgument), false);
var createHandle = function(myArgument) {
return function(event) {
.... do something
};
}
It still doesn't solve the fire twice issue though.
尽管如此,它仍然没有解决火灾两次问题。
回答by strah
addEventListenerregisters as many listeners as it is used.
addEventListener注册尽可能多的监听器。
According to the documentationit takes 3 arguments, the third is useCapturewhich has nothing to do with registering listener twice or not. It is by default set to false, so adding falseas a third parameter doesn't change much.
根据文档,它需要 3 个参数,第三个参数useCapture与两次注册侦听器无关。它默认设置为false,因此添加false为第三个参数不会有太大变化。

