That’s because HTMLCollection
returned by getElementsByClassName
is live.
That means that if you add "class"
to some element’s classList, it will magically appear in temp
.
The oposite is also true: if you remove the "class"
class of an element inside temp
, it will no longer be there.
Therefore, changing the classes reindexes the collection and changes its length. So the problem is that you iterate it catching its length beforehand, and without taking into account the changes of the indices.
To avoid this problem, you can:
-
Use a non live collection. For example,
var temp = document.querySelectorAll(".class");
-
Convert the live
HTMLCollection
to an array. For example, with one of thesetemp = [].slice.call(temp); temp = Array.from(temp); // EcmaScript 6
-
Iterate backwards. For example, see @Quentin’s answer.
-
Take into account the changes of the indices. For example,
for (var i=0; i<temp.length; ++i) { temp[i].className = "new_class"; --i; // Subtract 1 each time you remove an element from the collection }
while(temp.length) { temp[0].className = "new_class"; }