Beysinvader Beysinvader - 1 day ago 4
HTML Question

Javascript: getElementsByClassName not giving all elements

Well i put tablerows with a classname "gone" in my Html like this:

<tr class="gone">
<th>text</th>
<td>text</td>
</tr>
<tr class="gone">
<th>text</th>
<td>text</td>
</tr>
<tr class="gone">
<th>text</th>
<td>text</td>
</tr>
<tr class="gone">
<th>text</th>
<td>text</td>
</tr>
<tr class="gone">
<th>text</th>
<td>text</td>
</tr>
<tr class="gone">
<th>text</th>
<td>text</td>
</tr>


and when i get my elements in javascript with this code:

var arrayelements=document.getElementsByClassName('gone');
var arrlength=arrayelements.length;
for(var i=0;i<arrlength;i++){
arrayelements[i].setAttribute("class","there");
console.log(arrayelements);
}


the return value of my console.log is

> <tr class="there">...</tr>
> <tr class="there">...</tr>
> <tr class="there">...</tr>
> undefined


the next time i run it the result is

> <tr class="there">...</tr>
> <tr class="there">...</tr>
> undefined


i don't understand why it is suddenly undefined

Answer

the HTMLCollection returned by getElementsByClassName is a LIVE LIST ... by changing the class, you change the list during the for loop!

One solution is to "copy" the list to an array

var arrayelements=Array.prototype.slice.call(document.getElementsByClassName('gone'));
var arrlength=arrayelements.length;
for(var i=0;i<arrlength;i++){
    arrayelements[i].setAttribute("class","there");
    console.log(arrayelements);
}

Another method would be to start at the end of the list and work backwards

var arrayelements=document.getElementsByClassName('gone');
var arrlength=arrayelements.length;
for(var i=arrayelements.length-1;i>=0;i--){
    arrayelements[i].setAttribute("class","there");
    console.log(arrayelements);
}

or another - always work on the first element, seeing as you're always shrinking the length

var arrayelements=document.getElementsByClassName('gone');
while(arrayelements.length) {
    arrayelements[0].setAttribute("class","there");
}

I would recommend the first as the easiest to work with, and avoid the last method :p

Comments