For a loop, it repeats only once when trying to remove classes from elements

In Javascript, I have a function that should find elements on a page that have a "connected" class, and when I click a button, the classes for these elements are cleared. I wrote this code:

var prev_connected = document.getElementsByClassName("connected"); if (prev_connected.length > 0) { for (var j = 0; j < prev_connected.length; j++) { prev_connected[j].removeAttribute("class"); } } 

However, it only removes the class attribute of the first "connected" element on the page. When I have two β€œconnected” elements, I confirmed that the prev_connected array has 2 values, but for some reason the for loop never reaches the second. Is there something I'm doing wrong? Thanks.

+6
source share
3 answers

The result of getElementsByClassName is live, which means that when you remove a class attribute, it will also remove this element from the result. Using querySelectorAll more widely supported and returns a static NodeList.

In addition, you can iterate over a list more easily using the for ... in loop.

I would not recommend making an extra copy of the live list, to make it static , you should use a method that returns a static NodeList.

 var prev_connected = document.querySelectorAll(".connected"); document.getElementById('demo').onclick = function() { for(var i in Object.keys(prev_connected)) { prev_connected[i].removeAttribute("class"); } } 
 .connected { background: rgb(150,200,250); } 
 <div class="connected">Hello</div> <div class="connected">Hello</div> <div class="connected">Hello</div> <div class="connected">Hello</div> <div class="connected">Hello</div> <button id="demo">Remove the classes!</button> 
+4
source

This is because prev_connected is a living nodelist. When you update an element with this class, it removes it from the nodelist, which means that the length of the nodelist is reduced by one, which means that j trying to find element 2 in the nodelist of length 1, so it does not work after the first iteration.

This can be seen on the console in this demo .

One way to fix this is to convert the nodelist to an array:

 var prev_connected = [].slice.call(document.getElementsByClassName("connected")); 
+2
source

You have to iterate backwards and use elem[i].classList.remove('name') to remove the class name from each Demo element

 document.getElementById("button").onclick = function () { var prev_connected = document.getElementsByClassName("connected"); console.log(prev_connected); for (var i = prev_connected.length - 1; i >= 0; i--) { prev_connected[i].classList.remove("connected"); console.log(i, prev_connected[i - 1]); } } 

There are more answers: fooobar.com/questions/995186 / ...

0
source

All Articles