事件处理程序中的参数 - Javascript

parameters in event handlers - Javascript

我有一个事件侦听器,其中包含一个事件处理程序 和参数 ... 它可以工作 ... 而且,从我读到的内容来看,这是不应该的。当我将事件处理程序包含在匿名函数中时,就像(我认为)我应该的那样,它停止工作。

我在这个论坛上搜索过类似的问题,所有问题的回答都是一样的(释义):"if you want parameters in your event handler, you have to put it in an anonymous function."

抱歉,如果这是一个普通的问题,我是新手(我确实搜索过重复的问题):但是,为什么这样做有效,更重要的是,有没有更好的方法来做到这一点?



[澄清信息:我在一个页面上有 5 个按钮,因此循环。每个按钮控制网页的不同区域(但使用相同的操作,将 css 样式从 "display:none" 更改为 "display:block")——这就是为什么我需要一对一的对应关系一个单独的按钮和一个单独的 "details" 标签,因此需要在事件处理程序中使用参数。最后,按钮切换,因此 "if ... else".]


p.s 我有一个暂时在线的页面,所以你可以看看它是如何工作的(它只是一个 "notes to myself" 页面并且不完整):http://www.mylescallan.com/gameDesign/gameDesignIntroduction.html


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

if you want parameters in your event handler, you have to put it in an anonymous function.

不完全是。如果你想在你的事件处理程序中使用与迭代相关的参数,你必须将处理程序放在它自己的 scope 中,其中存储了这些参数。

现在,这个范围通常是通过使用 IEFE (see here 来实现的,例如,通常是匿名的。但是,您也可以在不影响处理程序行为的情况下命名它们。

在您的示例代码段中,none 函数是匿名的,它们的名称非常明确。 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);