Javascript 在循环中使用参数对addEventListener进行函数调用

Javascript 在循环中使用参数对addEventListener进行函数调用,javascript,Javascript,问题:我想调用一个函数“test”,使用按钮的click事件传递参数 使用addEventListener('click',test)工作 使用addEventListener('click',测试(参数))加载时自动激活该功能,而不单击按钮 问题:如何传递参数 //create 3 button (n is a counter): var btn = document.createElement("INPUT"); btn.setAttribute("id", "dem

问题:我想调用一个函数“test”,使用按钮的click事件传递参数

使用
addEventListener('click',test)工作

使用
addEventListener('click',测试(参数))加载时自动激活该功能,而不单击按钮

问题:如何传递参数

//create 3 button (n is a counter):
    var btn = document.createElement("INPUT");
        btn.setAttribute("id", "demo"+n);
        btn.setAttribute("type", "button");
        btn.setAttribute("value", ("click"));
        document.body.appendChild(btn);
不带参数的调用工作正常:

function test(m) {
    alert("YOU CLICKED ME!");
}

var m=0;
while(m!=3){
        document.getElementById("demo"+m).addEventListener("click", test);
        m=m+1;
}   
`

参数不工作时(功能立即激活):


将函数包装到另一个函数中,以避免立即调用它

document.getElementById("demo"+m).addEventListener("click",(function(x){
    return function(){
        test(x);
    }
})(m));
在您的例子中,addEventListener需要一个函数对象,因此在函数调用函数并传递返回值时,不能在函数前面使用括号。因此,您需要返回调用测试函数的函数对象(使用匿名函数避免javascript函数的闭包属性)

编辑:使用匿名函数返回测试的包装函数的原因

我们不能通过

function(){
    test(m);
}
直接添加到addEventListener。 因为javascript中的每个函数对象都会记住其词法范围之外的环境(
,在本例中为变量m
)。如果您只是在同一环境(
变量m
)中创建不同的函数(如while循环),那么它们将引用同一环境

您有两种方法可以使用如上所述的方法。

尝试以下方法:

function test(m) {
    alert("YOU CLICKED ME!"+m);
}

var m=0;
while (m!=3) {
    (function(m) {
        document.getElementById("demo"+m).addEventListener("click", function() {
            test(m);
        });
    })(m);
    m=m+1;
}   

这将为内部到循环的变量创建新的作用域。

您需要使用所谓的“高阶函数”构建
test
函数的版本:

另外,为了清晰起见,您可能需要在此处为
循环使用

for (var m = 0; m < 3; m++) { ... }
for(var m=0;m<3;m++){…}

解释为什么
addEventListener('click',test(parameter))
不起作用

addEventListener
函数可以接受两个参数,一个是事件类型,另一个是接收事件的侦听器对象。在大多数情况下,侦听器对象只是一个JavaScript函数

所以当你使用

addEventListener('click', test);
addEventListener('click', test(parameter));
您正在传递字符串
click
作为事件类型,传递函数
test
作为侦听器,这是您所期望的

但是当你使用

addEventListener('click', test);
addEventListener('click', test(parameter));
侦听器实际上是表达式
test(参数)
计算结果的值。由于
test(parameter)
是一个函数调用,您实际上传递了
test(parameter)
返回的内容,在您的情况下,
是“未定义的”
,因为
test
函数不返回任何内容。这就是为什么会立即调用
test
——需要调用它以获取返回值作为
addEventListener
函数调用的参数


因此,要在事件发生时使用自定义参数执行函数,正如其他人所建议的,您可以使用匿名函数方法。

这不起作用,您将始终在
m
中拥有循环的最后一个值。是的,忘记了闭包。谢谢修复