JS addEventListener参数

时间:2017-05-06 17:27:49

标签: javascript function events parameter-passing addeventlistener

我有一个包含多个表单(动态创建)的HTML页面,因此我将它们放入JS中的数组中,然后我为每个表单添加EventListener,如下所示:

var forms = document.getElementsByTagName('form');

for(i=0; i < forms.length; i++) {
    forms[i].addEventListener('change', function(){
        checkAllFilled(i);
    });
}

所以在函数checkAllFilled中我做了一些事情。

问题在于,如果我有7个表单(从forms[0]forms[6])并且我在forms[2]上工作,那么它总是被称为checkAllFilled(7),而不是调用{ {1}}。就像在for循环中的最后一个值中设置变量checkAllFilled(2)一样。

我该怎么做?

谢谢!

4 个答案:

答案 0 :(得分:4)

  

就像变量“i”被设置在for的最后一个值中   循环。

这正是发生的事情。

想一想。在for循环过去之后,您的事件处理程序将在稍后运行。那时,变量具有循环留给它的任何值 - 因此,事件将始终报告相同的单个值。

相反,您需要通过闭包绑定迭代值。有几种方法。一种是通过立即执行的功能(IEF)。

forms[i].addEventListener('change', (function(i) { return function(){
    checkAllFilled(i);
}; })(i));

我们将迭代值作为函数变量传递给IEF。这样,它通过闭包传递给处理程序。值得reading up on these

答案 1 :(得分:2)

另一种方法是使用ECMAScript 2015中的let。

for(let i=0; i < forms.length; i++) {
    forms[i].addEventListener('change', function(){
        checkAllFilled(i);
    });
}

答案 2 :(得分:1)

您总是调用最后生成的事件侦听器,因为您首先生成这些侦听器(都具有相同的名称),然后调用它们中的最后一个。

此处的最佳解决方案是根据计数器值i为

指定处理事件的函数的名称

答案 3 :(得分:1)

使用forEach()代替for循环:

var forms = document.getElementsByTagName('form');

[].slice.call(forms).forEach(function(form, i) {
    form.addEventListener('change', function(){
        checkAllFilled(i);
    });
});