1

Let's say I have a grid that looks like this (the numbers inside the cell is just for labeling, it could just be empty cells):

enter image description here

Written in HTML as follows:

<table>
      <tr>
        <td>0 </td>
        <td>1 </td>
      </tr>
      <tr>
        <td>2 </td>
        <td>3 </td>
      </tr>
</table>

There are two things that I would like to do:

  1. Add some JavaScript code that log the number of the cell to the console when each cell is clicked. Here is how I did it:
const cells = document.querySelectorAll('td');
for (var i = 0; i < cells.length; i++) {
  cells[i].addEventListener('click', function () {
    console.log(i);
  });
}

But the console always returns the value 4 wherever I click the table. My questions are:

  1. By adding cells[i].addEventListener in each iteration of the for loop, does it add an event listener for each cell?
  2. Why does the console always return 4 even if I clicked the cells[0], cells[\1], cells[2] or cells[3]?
  3. What should I do to make the console return the desired position in the array cells, i.e. return 0 if I clicked cells[0], return 1 if I clicked cells[\1], return 2 if I clicked cells[2], return 3 if I clicked cells[3]?

Next,

  1. The second thing that I would like to do is to change the colour of each cell depending on the colour that I chose from the colour picker as set by the HTML: <input type="color" id="colorPicker">

Here is how I did it:

const cells = document.querySelectorAll('td');
for (var i = 0; i < cells.length; i++) {
  cells[i].addEventListener('click', function () {    
    const color = document.querySelector('#colorPicker').value;
    cells[i].style.backgroundColor = color;
  });
}

But the colour of the cell did not change.

I don't plan to use jQuery, I would just like to use basic JavaScript that add an event listener to each cell. I have tried to figure some ways out for hours but still clueless in the end. Could somebody please give some help? I really appreciate it, thanks!

user71346
  • 703
  • 2
  • 10
  • 18
  • For more on why the event listeners added in the loop are all logging `4`, and the various ways to fix it, see this questions and its answers, as well as the several related ones: https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example – Robin Zigmond Sep 30 '18 at 10:50

2 Answers2

1

Since i is incrementing then after the for loop is complete i == cells.length.

in place of...

for (var i = 0; i < cells.length; i++) {
  cells[i].addEventListener('click', function () {
    console.log(i);
  });
}

use...

for (var i = 0; i < cells.length; i++) {
  cells[i].addEventListener('click', function (e) {
    console.log(e.target);
  });
}

And the same for your latter example...

user3094755
  • 1,561
  • 16
  • 20
0

is because you use "i" variable on your callback. And "i" have value : 4 at the end of your loop, so when you click callback, your app use this last value.

Just change your code by :

const cells = document.querySelectorAll('td');
for (var i = 0; i < cells.length; i++) {
  console.log(cells[i].innerText);
  cells[i].addEventListener('click', (event) => {
    console.log(event.target.innerText); // Take the text node from the element who fire the click event.

    // If you don't want to use innerText, you can do like this.
        console.log(
           //We transform querySelectorAll to traversable array. Then we find index of current event target.
           Array.from(document.querySelectorAll('td')).findIndex(e => e === event.target)
        );

  });
}

And for you second case base on colorPicker :

const cells = document.querySelectorAll('td');
for (var i = 0; i < cells.length; i++) {
  cells[i].addEventListener('click', function (event) {    
    const color = document.querySelector('#colorPicker').value;
    event.target.style.backgroundColor = color;
  });
}

live sample

Yanis-git
  • 7,737
  • 3
  • 24
  • 41
  • Thanks a lot! Just one question for the first case, what if the cell has no text in it? We can no longer use .innerText right? Then how to print the position i of the array? – user71346 Sep 30 '18 at 10:51
  • i have updated my answer with another approch to find index ;) hope this will help you – Yanis-git Sep 30 '18 at 10:57