I have following elements in the page:
<div class="cl1 cl2"></div>
<div class="cl1 cl2"></div>
<div class="cl1 cl2"></div>
When I run this code:
<script>
var elems = document.getElementsByClassName("cl1");
for (var i = 0; i < elems.length; i++) {
console.log(i + ": " + elems[i].className);
}
</script>
I can see:
0 cl1 cl2
1 cl1 cl2
2 cl1 cl2
in console.
But this code:
<script>
var elems = document.getElementsByClassName("cl1");
for (var i = 0; i < elems.length; i++) {
console.log(i + ": " + elems[i].className);
elems[i].className = 'cl3'; // or = '' (removing all classes)
}
</script>
gives:
0 cl1 cl2
1 cl1 cl2
on first run, and:
0 cl1 cl2
on the second run.
What is the reason of not modifying all the elements? I can see that elems.length is reducing when we touch elems[i].className, but what is the reason?
If we put var n = elems.length and change for-loop with i < n we will get Cannot read property 'className' of undefined error.
The question is how to modify all the classes from the first time?
Because I believe the following code looks very silly:
var elems = document.getElementsByClassName("cl1");
while (elems.length) {
for (var i = 0; i < elems.length; i++) {
console.log(i + ": " + elems[i].className);
elems[i].className = 'cl3';
}
elems = document.getElementsByClassName("cl1");
}
The problem is that items is a live NodeList, meaning whenever you access items.length, the list is re-evaluated.
When you delete elements, the list becomes shorter, but you keep the index.
You could convert the NodeList to an array first
The array size won’t change when you delete the DOM elements.