Scope within a loop

hey y’all. So I keep running into this problem with my programs, I’m wondering if anyone can help me understand what’s happening.

in this scenario I have a 5 html elements. I do a querySelectorAll for this group of elements. Then I loop over the returned nodeList. I want to click on a selected node and change its style. What is the proper way to achieve this goal?

<svg>
<svg>
<svg>
<svg>
<svg>

var svg = document.querySelectorAll('svg');

for (var i = 0; i < svg.length; i++) {
  svg[i].onclick = () => {
    svg[i].style.fill = "black";
  };
}

you can add an event listener instead of onclick, seem to work better

1 Like
for (var i = 0; i < svg.length; i++) {
  svg[i].addEventListener("click", function () {
    svg[i].style.fill = "black";
    console.log(svg[i]);
    // ^^^ svg[i] is undefined
  });
}

I’m getting the same thing with the event listener

When that function (the event listener callback) is called, it has no idea what svg[i] is. But you can use the this keyword instead:

  svg[i].addEventListener("click", function() {
    this.style.fill = "black";
  });
1 Like

Use let instead of var for the for loop index.

var svg = document.querySelectorAll("svg");

for (let i = 0; i < svg.length; i++) {
  svg[i].onclick = () => {
    svg[i].style.fill = "black";
  };
}

Or use forEach which is just cleaner anyway.

svg.forEach((svg) => {
  svg.onclick = () => {
    svg.style.fill = "black";
  };
});

Edit: Code examples:
https://jsfiddle.net/e25kh10b/

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.