我在jsfiddle上乱搞了一些javascript,遇到了一个奇怪的问题。我似乎无法弄清楚为什么我无法通过for循环设置onclick
事件处理程序:
html:
<table border="1" cellspacing="1" width="500">
<tr id="headerRow">
<td>Header1</td>
<td>Header2</td>
<td>Header3</td>
<td>Header4</td>
</tr>
<tr>
<td>books</td>
<td>red</td>
<td>peas</td>
<td>321</td>
</tr>
<tr>
<td>tapes</td>
<td>blue</td>
<td>jello</td>
<td>654</td>
</tr>
</table>
在DOM ready中执行的js:
var arr = document.getElementById('headerRow')
.getElementsByTagName("td");
// Why does this work??
/*arr[0].onclick = function() { alert(arr[0].innerHTML); };
arr[1].onclick = function() { alert(arr[1].innerHTML); };
arr[2].onclick = function() { alert(arr[2].innerHTML); };
arr[3].onclick = function() { alert(arr[3].innerHTML); };
*/
//But this doesn't????
for(var i = 0; i < arr.length; i++) {
arr[i].onclick = function() { alert(arr[i].innerHTML); };
}
答案 0 :(得分:4)
i
不会包含&#34;当前索引&#34;就像你想要的那样,而是i
的最后一个值,即arr.length
一个快速的解决方案就是做这样的事情
for(var i = 0; i < arr.length; i++) {
(function(_i){
arr[_i].onclick = function() { alert(arr[_i].innerHTML); };
})(i);
}
它的作用是在您正在执行的语句的闭包内的新变量i
中捕获_i
的当前值,因此它会保持并且是每当你的onclick处理程序被调用时,你都期望得到它。
答案 1 :(得分:1)
你需要一个闭包,否则arr[i]
会在另一个范围内执行并且会爆炸。
for(var i = 0; i < arr.length; i++) {
arr[i].onclick = function(text) {
return function () {
alert(text);
};
}(arr[i].innerHTML);
}
答案 2 :(得分:0)
这是一个常见的错误。 i
是一个全局变量,你在for循环中递增。当循环结束时,我将等于4.然后在你的点击处理函数中,你试图显示arr[i].innerHTML
,现在是arr[4].innerHTML
。 arr[4]
显然不存在,因此您会收到错误。
要轻松解决问题,请将alert(arr[i].innerHTML)
更改为alert(this.innerHTML)
。在单击处理函数的上下文中,this
将引用<TD>
元素。