事件处理程序作为名称与匿名函数

时间:2017-06-23 09:54:05

标签: javascript

在实现闭包函数时,我注意到如果我提供一个“命名函数”作为事件处理程序,那么当事件附加到按钮时它会立即执行。但是,如果我将函数作为匿名函数保持内联,那么它不会直接执行,只会在函数上触发 事件发生了。任何人都可以解释这种行为吗?

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");
      });
}

非常感谢!

3 个答案:

答案 0 :(得分:0)

这与被命名的函数无关。这是关于显式调用函数的代码。

如果您将(some,arguments)放在某个功能之后,则会调用它。

!foo() // calls the function
!function () { }(); // Also calls the function

所以:

button.addEventListener('click', buttonHandler(buttonName));
  1. 调用buttonHandler,将buttonName作为参数传递给它
  2. 致电addEventListener,传递"click"并将1的返回值传递给它
  3. 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);