if I use
var temp = document.querySelectorAll(\".class\");
for (var i=0, max=temp.length; i
Loop over the list backwards, then elements will vanish from the end (where you aren't looking any more).
for (var i = temp.length - 1; i >= 0; i--) {
temp[i].className = "new_class";
}
Note, however, that IE 8 supports querySelectorAll but not getElementsByClassName, so you might want to prefer querySelectorAll for better browser support.
Alternatively, don't remove the existing class:
for (var i=0, max=temp.length; i<max; i++) {
temp[i].className += " new_class";
}
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 these
temp = [].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";
}