Search code examples
javascripthtmlcollection

Empty array when using getElementsByTagName


How to I loop through the elements retrieved using document.getElementsByTagName(); as it's length is coming out to be 0 but still has elements.

Below is the JS code:

class HKPlayer
{
    constructor()
    {
        this.getPlayers();
        this.getPlayerAttributes();
    }
    getPlayers()
    {
        this.players = document.getElementsByTagName("HKPlayer");
    }
    getPlayerAttributes()
    {
        console.log(this.players);
    }
}
(function () {
    new HKPlayer();
})();

below is the html code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>HKPlayer Demo</title>
    <script src="dist/HKPlayer.js" type="text/javascript"></script>
</head>
<body>
    <HKPlayer type="video" theme="dark" src="assets/video/1.mp4"></HKPlayer>
    <br/>
    <HKPlayer type="video" theme="dark" src="assets/video/2.mp4"></HKPlayer>
</body>
</html>

The output is like:

enter image description here

enter image description here

I cannot loop through this.players as the array this.players array is empty. how do I do that.


Solution

  • You're executing your JS before the DOM is loaded.

    Try wrapping this part of your code:

    (function () {
        new HKPlayer();
    })();
    

    Inside this:

    document.onreadystatechange = function()
    {
        if(document.readyState === 'complete')
        {
            // Put your code that relies on a complete/ready DOM here.
        }
    }
    

    EDIT: As a response to the comment, no this is not 100% cross-browser, nor will it always work. If you want as much browser-support as possible, you'd most likely want to use the following methods:

    document.addEventListener('DOMContentLoaded', fn, false);
    

    with a fallback to:

    window.addEventListener('load', fn, false )
    

    or for older versions of IE:

    document.attachEvent("onreadystatechange", fn);
    

    with a fallback to:

    window.attachEvent("onload", fn);
    

    This is apparently how jQuery handles its $(document).ready(). More information about this can be found here.