Michael Bluejay
Michael Bluejay

Reputation: 70

How to use variables in an Unobtrusive Javascript onclick assignment?

I'm trying to assign onclicks to td's in the first row, such that a click on the first TD outputs "1", a click on the second TD outputs "2", etc.

The problem is that when I actually click to call the onclick, I always get "3", because that was the last value of the variable that the onclick uses.

Is there a way to get each onclick to return the unique number I want?

window.onload = function() { //Wait for the DOM to load.
    table = document.getElementById('myTable');
      for (i = 0; cell = table.rows[0].cells[i]; i++) {
        console.log(i); // logs 0, 1, 2
        cell.onclick=function(){ console.log(i);} // Want to get 0,1, or 2, but always get 3.
    }
}
<table id=myTable>
    <tr>
        <td>COL1</td>
        <td>COL2</td>
        <td>COL3</td>
    </tr>
    <tr>
        <td>one</td>
        <td>two</td>
        <td>three</td>
    </tr>
    <tr>
        <td>four</td>
        <td>five</td>
        <td>six</td>
    </tr>
</table>

Upvotes: 0

Views: 53

Answers (1)

choz
choz

Reputation: 17848

That's because the i value is looking up to the nearest closure variable, if its not found, then it will be global. In your code it's global and mutated until the loop finishes.

Simply have i itself as a block-scoped variable

for (let i = 0; cell = table.rows[0].cells[i]; i++) {

Or assign it to another, in the following example, it's idx.

<table id=myTable>
  <tr>
    <td>COL1</td>
    <td>COL2</td>
    <td>COL3</td>
  </tr>
  <tr>
    <td>one</td>
    <td>two</td>
    <td>three</td>
  </tr>
  <tr>
    <td>four</td>
    <td>five</td>
    <td>six</td>
  </tr>
</table>

<script>
  window.onload = function() { //Wait for the DOM to load.
    table = document.getElementById('myTable');
    for (i = 0; cell = table.rows[0].cells[i]; i++) {
      console.log(i); // logs 0, 1, 2
      let idx = i;
      cell.onclick = function() {
        console.log(idx);
      } // Want to get 0,1, or 2, but always get 3.
    }
  }
</script>

Upvotes: 2

Related Questions