函数调用带有addEventListener参数的循环内部

时间:2015-05-20 15:31:07

标签: javascript

问题:我想调用一个函数" test"使用按钮的单击事件传递参数。

使用addEventListener ('click', test );有效。

使用addEventListener ('click', test(parameter));加载时自动激活该功能,而不是单击按钮。

问题:如何传递参数?

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

`

参数不起作用(该功能立即激活):

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

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

4 个答案:

答案 0 :(得分:5)

将您的函数包装在另一个函数中以避免立即调用它

document.getElementById("demo"+m).addEventListener("click",(function(x){
    return function(){
        test(x);
    }
})(m));

在你的情况下,addEventListener需要一个函数对象,因此你不能在函数前面使用括号,因为它调用函数并传递返回值。所以你需要返回调用测试函数的函数对象(使用匿名函数来避免javascript函数的闭包属性)

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

我们无法通过

function(){
    test(m);
}

直接添加事件。 由于javascript中的每个函数对象都会记住其词法范围之外的环境(in our case variable m)。如果你只是在同一个环境(variable m)中创建不同的函数(比如在while循环中),那么它们将引用相同的环境。

您有两个使用function factory to avoid creating closures in loop,如上所述。

答案 1 :(得分:1)

试试这个:

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

答案 2 :(得分:1)

解释addEventListener('click', test(parameter))无效的原因

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

所以当你使用

addEventListener('click', test);

您将字符串click作为事件类型传递,并将函数test作为侦听器传递,这是您所期望的。

但是当你使用

addEventListener('click', test(parameter));

侦听器实际上是表达式test(parameter)计算的值。由于test(parameter)函数调用,因此您实际上会传递test(parameter)返回的内容,在您的情况下'undefined',因为test函数确实不归还任何东西。这就是立即调用test的原因 - 需要调用它来获取返回值作为addEventListener函数调用的参数。

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

答案 3 :(得分:0)

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

// this is a high order function, since it returns a function
function buildTestFunction(m) {
  return function () {
    alert("YOU CLICKED ME!"+m);
  };
}

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

PS。为清晰起见,您可能需要在此处使用for循环。

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