This question already has answers here:
Closed 7 years ago.
I was messing around with some javascript, on jsfiddle, and ran into a strange issue. I can't seem to figure out why I am unable to set onclick
event handlers via a for loop:
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>
js executed in DOM ready:
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); };
}
http://jsfiddle.net/xzmMj/4/
i
will not contain the "current index" like you are intending, but rather the last value i
was, ie arr.length
One quick n dirty solution would be to do something like this
for(var i = 0; i < arr.length; i++) {
(function(_i){
arr[_i].onclick = function() { alert(arr[_i].innerHTML); };
})(i);
}
what this does is captures the current value of i
in a new variable _i
within the closure of the statement you're executing, so it'll stay around and be the value you'd expect every time your onclick handler is called.
You need a closure, otherwise the arr[i]
executes in an alternate scope and blows up.
for(var i = 0; i < arr.length; i++) {
arr[i].onclick = function(text) {
return function () {
alert(text);
};
}(arr[i].innerHTML);
}
http://jsfiddle.net/xzmMj/5/
This is a common error. i
is a global variable that you're incrementing in the for loop. When the loop finishes, i will be equal to 4. Then in your click handler function, you're trying to display arr[i].innerHTML
, which is now arr[4].innerHTML
. arr[4]
obviously doesn't exist, so you get an error.
For an easy fix, change alert(arr[i].innerHTML)
to alert(this.innerHTML)
. this
, in the context of the click handler function, will refer to the <TD>
element.