Javascript循环中的事件处理程序 - 需要一个闭包吗?

时间:2008-12-04 19:15:42

标签: javascript dom loops closures

我正在处理一些我从其他人手中接过的HTML和Javascript代码。该页面每十秒重新加载一个数据表(通过异步请求),然后使用一些DOM代码重新构建表。有问题的代码看起来像这样:

var blah = xmlres.getElementsByTagName('blah');
for(var i = 0; i < blah.length; i++) {
    var td = document.createElement('td');
    var select = document.createElement('select');
    select.setAttribute("...", "...");
    select.onchange = function() {
        onStatusChanged(select, callid, anotherid);
    };
    td.appendChild(select);
}

但是,当为onchange元素触发<select>事件时,表格中的每个onStatusChanged()的{​​{1}}方法似乎都会传递相同的值(我已经验证了在循环的每次迭代中,<select>callid都被赋予了新的不同值。

我怀疑这是因为我使用anotherid语法设置事件处理程序的性质。如果我理解这是如何正常工作的,那么这个语法将onchange事件的闭包设置为一个函数,该函数引用这两个引用,最终得到它们在循环的最后一次迭代中设置的最终值。触发事件时,select.onchange = function()callid引用的值是上次迭代中设置的值,而不是单个迭代中设置的值。

有没有办法可以将我传递的参数值复制到anotherid

我更改了标题以更好地反映问题和接受的答案。

1 个答案:

答案 0 :(得分:50)

你确实需要在这里实现一个闭包。这个应该工作(让我知道 - 我没有测试它)

var blah = xmlres.getElementsByTagName('blah');
for(var i = 0; i < blah.length; i++) {
    var td = document.createElement('td');
    var select = document.createElement('select');
    select.setAttribute("...", "...");
    select.onchange = function(s,c,a)
    {
        return function()
        {
            onStatusChanged(s,c,a);
        }
    }(select, callid, anotherid);
    td.appendChild(select);
}