Search code examples
javascriptgetelementbyid

unable to use getElementById on HTML element not yet appended to document


I have the following bit of js which creates a div, doesn't yet append it to the page but does populate it with some HTML. I can query that HTML with getElementsByClassName as shown in the alert which correctly alerts as "2".

However trying to use getElementById on the same element results in an error "Object doesn't support property or method 'getElementById'"

function verbatim(fn) {
    return fn.toString().split("/*")[1].split("*/")[0];
}

var aggregatorContainer = document.createElement("div");
aggregatorContainer.id = "usageByCampusNow";

var someHTML = verbatim(function () {/*
            <h2>Lab Locations and Current Use</h2>

            <div class='campusIndicator master'>
                <div id='masterAggregator'>

                    <div id='masterSelector'>
                        <div class='aggDetails'>
                            <h3 id="masterSelection"></h3>
                        </div>
                    </div>
                    <div id='masterOptions'><ul id='masterOptionsList'></ul></div>

                    <div class='guageContainer'>
                        <div class='campusGuage'>
                            <span><img class='clockhand' src='/images/labs/handred2.png'></span>
                            <span><img class='clockhand' src='/images/labs/hand2.png'></span>
                        </div>
                        <span class='txtUse'></span>
                    </div>
                </div>
            </div>
        */
});

aggregatorContainer.innerHTML = someHTML;
alert(aggregatorContainer.getElementsByClassName("clockhand").length);
try {
    var masterAggContainer = aggregatorContainer.getElementById("masterAggregator"); // issue
}
catch (err) {
    alert(err); // Object doesn't support property or method 'getElementById'
}

https://jsfiddle.net/4zougwm9/

The simple solution is that I add the element to the page

 document.getElementById("someElement").appendChild(aggregatorContainer);

and then I can use document.getElementById to get elements within aggregatorContainer to my hearts delight but I was hoping that I could do all the prep on the HTML before appending it to the page in case something went wrong and I ended up with a funky element stinking up the page. So I'd like to query aggregatorContainer.getElementById before adding it to the page

Essentially, why can't I use getElementById on this element before it's appended? getElementsByClassName seems to be fine!


Solution

  • From MDN documentation for Document.getElementsByClassName:

    • getElementsByClassName can be called on any element, not only on the document. The element on which it is called will be used as the root of the search.

    https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName

    Document.getElementById does not have that note: https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById

    The difference is that getElementsByClassName seems to be inherited by NodeLists from Document whereas getElementById is not. The reason I assume is that getElementsByClassName returns what it is working on , which is a NodeList or HTMLCollection, thus allowing for chainability; whereas getElementById will always return zero or one Nodes or HTMLElements.