我有一个事件监听器,它包含一个带有参数的事件处理程序 ......它可以工作......而且,从我读过的,它不应该。当我在一个匿名函数中包含事件处理程序时,就像(我认为)我应该这样,它就会停止工作。
我在这个论坛上搜索过类似的问题,所有的问题都以同样的方式回答(释义):"如果你想在事件处理程序中使用参数,你必须把它放在一个匿名函数中。&# 34;
道歉,如果这是一个平凡的问题,我是新手(我确实在搜索重复的问题):但是,为什么这样做,更重要的是,有更好的方法来做到这一点?
[澄清信息:我在页面上有5个按钮,因此循环。每个按钮控制网页的不同区域(但是使用相同的动作,从&#34更改css样式;显示:无"到"显示:块") - 这就是为什么我需要一个个人按钮与个人之间的对应关系"详细信息" tag,因此需要事件处理程序中的参数。最后,按钮切换,因此" if ... else"。]
ps我暂时在线放置一个页面,这样你就可以看到它是如何工作的(它只是一个"自己的注释"页面并且不完整):http://www.mylescallan.com/gameDesign/gameDesignIntroduction.html {{3 }}
var buttons = document.getElementsByClassName("expand"),
details = document.getElementsByClassName("reveal"),
i;
function makeClickHandler(details, i) {
"use strict";
function myHandler() {
if (details[i].style.display === 'block') {
details[i].style.display = 'none';
buttons[i].innerHTML = "<em>Click Here:</em> To Expand The Source Code For This Section";
buttons[i].style.opacity = "1";
} else {
details[i].style.display = 'block';
buttons[i].innerHTML = "<em>Click Here<em>: Don't Forget To Hide This Section, You've Read It";
buttons[i].style.opacity = "0.5";
}
};
return myHandler;
}
for ( i = 0; i < buttons.length; i++) {
buttons[i].addEventListener("click", makeClickHandler(details, i), false);
}
答案 0 :(得分:1)
如果您想在事件处理程序中使用参数,则必须将其放在匿名函数中。
不完全是。如果您想在事件处理程序中使用与迭代相关的参数,则必须将处理程序放在其自己的范围中,并存储这些参数。
现在,通常使用IEFE(请参阅here示例)来实现此范围,这通常是匿名的。但是,您也可以在不影响处理程序行为的情况下对它们进行命名。
在您的示例代码段中,没有一个函数是匿名的,它们是非常明确地命名的。 makeClickHandler()
确实为范围提供i
变量,其中myHandler
闭包存在。它正如预期的那样有效。
当你注意到
时,也许这有助于你的理解function makeClickHandler(details, i) {
return function myHandler(event) {
… // use details, i, event
};
}
for (var i = 0; i < buttons.length; i++)
buttons[i].addEventListener("click", makeClickHandler(details, i) , false);
// no call here ^
相当于
function addClickHandler(button, details, i) {
function myHandler(event) {
… // use details, i, event
}
button.addEventListener("click", myHandler , false);
// no call here ^ (that's what is said everywhere)
}
for (var i = 0; i < buttons.length; i++)
addClickHandler(buttons[i], details, i);