0

I have a question on the following for loop in javascript - the purpose of the for loop is simple, they are meant to listen to the event for all of the columns that i have.

I have two methods to achieve this, i wonder why one works but not another.

First method that DOES NOT work:

var column = document.querySelectorAll("td");

for (var i =0 ; i< column.length; i++)//column.length is 9
{
column[i].addEventListener("click",function(){
column[i].innerText = "X";
})
}

it prints out the following error when the event is triggered:

Uncaught TypeError: Cannot set property 'innerText' of undefined at HTMLTableCellElement. (:6:21)

I replaced "column[i].innerText = "X" with console.log(i), i get 9. But according to my for loop condition, it is supposed to end when i reaches 8 as my column.length is 9, and i use i < column.length, so it should stop at 8.

Question: Why can i get 9 in this for loop ? And why my second approach below can work ?

Second method that DOES work:

var column = document.querySelectorAll("td");

for ( var i = 0 ; i < column.length; i++ )
{
    column[i] = clickAction(i);
}

function clickAction(param)
{
    column[param].addEventListener("click",function(){  
    column[param].innerText = "X";  
})
}

It works fine if i put the action into a function externally.

Thanks

csamleong
  • 769
  • 1
  • 11
  • 24
  • Please see https://stackoverflow.com/questions/1451009/javascript-infamous-loop-issue and https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example – Rob M. Apr 08 '17 at 03:24
  • Thanks for the reply. After reading the links that you have posted: i have found out that the link below helps me to understand this problem easily. http://conceptf1.blogspot.my/2013/11/javascript-closures.html – csamleong Apr 08 '17 at 03:49

2 Answers2

0

In the first method when your loop exist that time value of i is 9 and it register events on all column with value 9. So when you fire the event it throws an error.

Sumit Gulati
  • 665
  • 4
  • 14
0

i found out that to avoid this problem, other than calling the function externally, i can also do the following:

var column = document.querySelectorAll("td");

for (var i =0 ; i< column.length; i++)//column.length is 9
{
column[i].addEventListener("click",function(){
this.innerText = "X"; //using this keyword here so that current object is being called.
})
}
csamleong
  • 769
  • 1
  • 11
  • 24