'HTML getElementsByClassName returns HTMLCollection with length of 0

I am trying to use the js document.getElementsByClassName to locate an html element, which is actually the header of a table.

For the following codes:

console.log(document.getElementsByClassName('gtableheader'));

From the Firebug, I can see it log a HTMLCollection, and when I click it, it shows:

-> 0         tr.gtableheader
   length    1

So it do locate the element I want.

But when I using:

console.log(document.getElementsByClassName('gtableheader').length);

Then output is 0. That's so weird, any ideas about this?



Solution 1:[1]

Using getElementsByClassName() will return all the elements with that class name in a document as a NodeList. This object represents a collection of nodes that can be accessed by index numbers, which starts in 0. In order to access the elements in the NodeList you will have to use a loop.

When you console.log(document.getElementsByClassName('gtableheader').length); you see 0 because when you run it there is no element with class gtableheader. You are able to see the items in the console because document.getElementsByClassName() returns a live collection that is updated when the new elements are added.

As well, in the code you are using and the length is 0, you can use the code below to access the class name.

document.getElementsByClassName('gtableheader')[0].style.color="red";

If you want to access all the elements in the class you can use a for loop.

var x = document.getElementsByClassName('gtableheader');
for (var i = 0; i < x.length; i++) {
    x[i].style.color = "red";
}

More information: http://www.w3schools.com/jsref/met_document_getelementsbyclassname.asp

Solution 2:[2]

That's because the getElementsByClassName returns a live collection. the length property of the object is 0 because at that point of time there is no element with that className in the DOM. Since the console shows the live representation of an object, it shows all the matching elements when the elements are added to the DOM.

DOM parser parses the documents from top to bottom, when it reaches to a tag, it parses it and adds the DOM representation of it (an instance of HTMLElement interface) to the Document Object Model. You should either move the script tag to the end of body tag or listen to DOMContentLoaded event which is fired when the initial HTML document has been completely loaded and parsed.

Solution 3:[3]

Use this to make it work

window.addEventListener("load", function(event) {
    console.log(document.getElementsByClassName('gtableheader').length);
});

Solution 4:[4]

I had a similar problem, but the other answers here didn't lead to my solution. I eventually realized that at the time my code was running, the DOM wasn't yet fully constructed, thus the empty array. What I was seeing in the console, a populated array, was what existed after the DOM was fully formed and the script was complete.

What worked for me was to wrap the code that needed the array within a MutationObserver and set it to watch the hard-coded div containing the sections that would be dynamically generated (see this StackOverflow answer and the MDN documentation).

Try this:

var divArray = document.getElementById('hardCodedContainer');

var observer = new MutationObserver(function(){
   console.log(document.getElementsByClassName('gtableheader').length);
   console.log(document.getElementsByClassName('gtableheader'));
};

observer.observe(divArray, { attributes: false, childList: true, subtree: true });

// When you've got what you need, you should call this function to trigger a disconnect 
function classesFound(){
   observer.disconnect();
};

Solution 5:[5]

I had this problem asking for the elements just after its dynamic creation, fixed with setTiemout()

Solution 6:[6]

You just need to call the js file after the html code where the classes are declared.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3
Solution 4 jamesthe500
Solution 5 martindhx
Solution 6 zdig