Why my getElementsByTagName returns an empty NodeList?

javascript

Solution

You'll find that a `<h1>` cannot contain another heading (the only valid content of an `h1`, and other headings, is phrasing content, which restricts content to, very simplistically, in-line elements and text), therefore when the browser constructs the DOM it moves the `h2` elements outside of the `h1`, which prevents them being found, by the DOM, inside the `h1`.

In Chrome, your HTML is reorganised to the following (and, I presume, similarly rearranged in other browsers):

<h1 id="hg"></h1>
<h2>11</h2>
<h2>22</h2>
<h2>33</h2>

This rescuing of the DOM to maintain validity is why we should, as developers, always strive to create valid HTML: because the automatic corrections made by browsers are undocumented and unpredictable (prior to HTML 5, which I think documents how error recovery should proceed).

Incidentally, this sounds very similar to the use-case presented for the `<hgroup>` element (which seems to be in the process of being dropped from the spec). Given, however, that you appear to be presenting a list of contents I'd suggest enclosing the `<h2>` elements in an `<ol>` and semantically grouping them that way:

<ol id="contents">
    <li><h2>11</h2></li>
    <li><h2>22</h2></li>
    <li><h2>33</h2></li>
</ol>

Problem

This is my code: ``` <html> <h1 id="hg"> <h2>11</h2> <h2>22</h2> <h2>33</h2> </h1> <script> var h = document.getElementById("hg").getElementsByTagName("h2"); alert(h.length); </script> </html> ``` I have looked up the manual, it seems that `getElementById` returns an `HTMLHeadingElement` in this case, and it inherits the method `getElementsByTagName` from `Element`. I expect to get a `3` as the value of `h.length`, but instead I get `0`. What's wrong with it?

Original source