0

I have two event listeners and I have a counter. When I click the element, I always get the last number of the counter.

How can I get or pass the correct counter.

let i = 0;
document.querySelectorAll('div').forEach(element => {
 element.addEventListener("click", () => {
   console.log(i);
 })
 i++;
});
<div>
Click me
</div>

<div>
Click me too
</div>
norbitrial
  • 14,716
  • 7
  • 32
  • 59
Jens Törnell
  • 23,180
  • 45
  • 124
  • 206

4 Answers4

3

The problem is when page loads, two div elements are found where click events have been attached and in the same time the variable i value has been increased two times. At the end on each click, you have logged value 2 into the console.

If you want to increase the number value on each click then you need to move i++ into the click event like the following:

let i = 0;
document.querySelectorAll('div').forEach(element => {
 element.addEventListener("click", () => {
    i++;
    console.log(i);   
 });
});
<div>Click me</div>
<div>Click me too</div>

I hope this helps!

norbitrial
  • 14,716
  • 7
  • 32
  • 59
2

You're incrementing i in the incorrect location. It should be in the click callback.

let i = 0;
document.querySelectorAll('div').forEach(element => {
 element.addEventListener("click", () => {
   i++;
   console.log(i);
 })
});
<div>
Click me
</div>

<div>
Click me too
</div>
Paul
  • 1,002
  • 4
  • 6
2

The increment(i++) should be inside the event handler:

let i = 0;
document.querySelectorAll('div').forEach(element => {
 element.addEventListener("click", () => {
   console.log(i);
    i++;
 })

});
<div>
Click me
</div>

<div>
Click me too
</div>
Addis
  • 2,480
  • 2
  • 13
  • 21
1

It is well known mistake in using callback in the loop. If you wish to have the number of the element clicked you need to use closure. Something like this.

let i = 0;
document.querySelectorAll('div').forEach(element => {
  ((j) => element.addEventListener("click", () => {
    console.log(j);
  }))(i);
  i++;
});
<div>
  Click me
</div>

<div>
  Click me too
</div>
Alex Kudryashev
  • 9,120
  • 3
  • 27
  • 36
  • Yes, that was what I was looking for. Thanks! In the meantime I found an alternative solution which is to add params to the event object and then get them later from there, see this solution: https://stackoverflow.com/a/11986895/148496 Not sure which way I prefer yet. – Jens Törnell Feb 08 '20 at 17:37