Reputation: 2960
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?
Upvotes: 2
Views: 3791
Reputation: 253396
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>
Upvotes: 9
Reputation: 35973
you need to change your html to this for example:
<div id="hg">
<h2>11</h2>
<h2>22</h2>
<h2>33</h2>
</div>
Upvotes: 1