Javascript循环中的事件处理程序 – 需要closures?
我正在处理一些我从其他人手中接过的html和Javascript代码。 该页面每十秒钟重新载入一个数据表(通过asynchronous请求),然后使用一些DOM代码重新构build表。 有问题的代码看起来像这样:
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); }
但是,如果为<select>
元素触发onchange
事件,则表中的每个<select>
都会将相同的值传递给onStatusChanged()
方法(我已经validation了在循环的每次迭代中, callid
和anotherid
正在被赋予新的,不同的值)。
我怀疑这是发生,因为我设置事件处理程序的性质,使用select.onchange = function()
语法。 如果我理解这是如何工作的,那么这个语法将onchange事件的闭包设置为一个引用这两个引用的函数,这个引用最终具有在循环的最后一次迭代中设置的最终值。 当事件触发时, callid
和anotherid
引用的值是最后一次迭代中设置的值,而不是单个迭代中设置的值。
有没有办法,我可以复制我传递给onStatusChanged()
参数的值?
我已经改变了标题,以更好地反映问题和接受的答案。
你确实需要在这里实施一个closures。 这应该工作(让我知道 – 我没有testing)
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); }