0

I create some image elements with JS, and I want that when I click in each image have a different number associated. But the problem is addEventListener just take the last number of the FOR. Some help pls.

For example, when I click on the second image the number that appear on the alert is 6.

body = document.body;
test = 1;

for (i = 0; i < 6; i++) {
  img = document.createElement('img');
  img.src = 'https://www.w3schools.com/images/w3lynx_200.png';
  img.addEventListener("click", function() {
    alert(test);
  });
  body.appendChild(img);

  test = test + 1;
}
isherwood
  • 58,414
  • 16
  • 114
  • 157

1 Answers1

2

The problem is that you've created a closure-- the click handler will refer to the value of test when it runs, which is after the loop has executed and increased the value of test to the number of items in the loop.

There's a few ways around this-- the easiest may be to put the number in a data attribute on the element and reference that data attribute:

test = 1;

for (i = 0; i < 6; i++) {
  let img = document.createElement('img');
  img.src = 'https://www.w3schools.com/images/w3lynx_200.png';
  img.dataset.idx = test;
  img.addEventListener("click", function(e) {
    console.log(e.target.dataset.idx);
  });
  document.body.appendChild(img);

  test = test + 1;
}

Or you can rewrite your function to eliminate the outer-closure, and use a closure variable block-scoped to the iteration:

for (i = 0; i < 6; i++) {
  let currentIndex = i;
  let img = document.createElement('img');
  img.src = 'https://www.w3schools.com/images/w3lynx_200.png';
  img.addEventListener("click", function(e) {
    console.log(currentIndex);
  });
  document.body.appendChild(img);
}
Alexander Nied
  • 12,804
  • 4
  • 25
  • 45