在实现闭包函数时,我注意到如果我提供一个“命名函数”作为事件处理程序,那么当事件附加到按钮时它会立即执行。但是,如果我将函数作为匿名函数保持内联,那么它不会直接执行,只会在函数上触发 事件发生了。任何人都可以解释这种行为吗?
var buttons = document.getElementsByTagName('button');
//function buttonHandler(buttonName){
//// return function(){
//// console.log(buttonName);
//// }
// alert("hello");
//}
var buttonHandler = function(name){
alert(name);
}
for(var i = 0; i < buttons.length; i += 1) {
var button = buttons[i];
var buttonName = button.innerHTML;
button.addEventListener('click', buttonHandler(buttonName));
button.addEventListener('click', function(buttonName){
alert("hi");
});
}
非常感谢!
答案 0 :(得分:0)
这与被命名的函数无关。这是关于显式调用函数的代码。
如果您将(some,arguments)
放在某个功能之后,则会调用它。
!foo() // calls the function
!function () { }(); // Also calls the function
所以:
button.addEventListener('click', buttonHandler(buttonName));
buttonHandler
,将buttonName
作为参数传递给它addEventListener
,传递"click"
并将1
的返回值传递给它 buttonHandler
没有return
语句,因此undefined
的返回值不是传递给addEventListener
的有用信息。
注释掉的buttonHandler
版本会返回一个函数。传递给addEventListener
会很有用。
答案 1 :(得分:-1)
正如前面的回答所指出的那样,添加处理程序的第一次尝试实际上是调用函数,而不是在事件被触发并调度处理程序时将其添加为执行的回调。 我还注意到您正在尝试将多个处理程序附加到同一事件。如果这对你有用,我建议如下:
button.addEventListener('click', (ev)=>{
// now supposing you have an array
// of handlers to execute, named
// handlers
handlers.forEach((handler)=>{
Object.prototype.call(handler, button); // here button is the execution context
});
}, false); // to prevent event from bubbling
答案 2 :(得分:-1)
正如上面代码
中的答案所指出的那样button.addEventListener('click', buttonHandler(buttonName));
正在直接调用该函数,所以如果你只需要将参数传递给处理函数,你可以使用匿名函数而不是直接调用这里推荐的函数(https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)
我更新了我的代码,如下所示
button.addEventListener('click', function (){ buttonHandler(buttonName)}, false);