2

How can I refer to a nested div by id when it has the same id as a div nested in a similarly named div

eg

<div id="obj1">
    <div id="Meta">
        <meta></meta>
    </div>
</div>

<div id="obj2">
    <div id="Meta">
        <meta></meta>
    </div>
</div>

I want to get the innerHTML of meta

document.getElementById('obj1').getElementById('Meta').getElementsByTagName('meta')

doesn't work

7 Answers 7

24

IDs should only be used when there is one of that item on the page, be it a SPAN, DIV or whatever. CLASS is what you should use for when you may have a repeating element.

Code there doesn't work because you're referring to an element by unique ID, but have more than one on the page.

10

Id is supposed to be unique.

2
  • interesting point /= I guess seeing as it's already been programmed with the named Id's I'm kind of stuck to go and change them
    – Supernovah
    Commented Mar 6, 2009 at 1:40
  • yeah, you're kind of screwed unless you can change that. Commented Mar 6, 2009 at 1:45
7

Hate to point out the obvious, but in your example, obj1_Meta and obj2_Meta are unique id's, so if it's the case in your working code:

document.getElementById('obj1_Meta').getElementsByTagName('meta')[0].innerHTML;

would work as described. As a double check, did you over think this?

If not, bummer...

As "bad" or "wrong" as your code is, an option that will work is to use a JavaScript framework like jQuery. Once you've included it, you can get elements by passing it a CSS selector (even a semantically incorrect one) like so:

$('#obj1 #obj1_Meta meta').html()

$() is jQuery's way of saying document.getElementById() ...on steroids. .html() is its equivalent of .innerHTML

Other frameworks, like PrototypeJS and MooTools also provide similar functionality.

Prototype for example:

$$('#obj1 #obj1_Meta meta').innerHTML;//note the double $'s

Frameworks save lots of time and trouble with regard to browser compatibility, "missing" JavaScript methods (like getElementsByClassName) and coding AJAX quickly. These things make them a good idea to use to anyway.

6

IDs are meant to be unique, use classes intelligently.

<div id="obj1" class="obj">
    <div id="obj1_Meta" class="obj_Meta">
        <meta></meta>
    </div>
</div>

<div id="obj2" class="obj">
    <div id="obj2_Meta" class="obj_Meta">
        <meta></meta>
    </div>
</div>
  • .obj = targets both elements
  • #obj1.obj = targets only the first
  • #obj1.obj_Meta = targets obj1 inner DIV
  • #obj2.obj = targets only the second
  • #obj2.obj_Meta = targets obj2 inner DIV
5

You may also run into problems with this markup because the "meta" tag is only legal inside the head tag, not the body tag. As far as I can tell from looking at Firebug, Firefox will even go so far as to pull those meta tags out of the body and toss them into the head (and, in this case, put any text content inside the parent div), so you won't see them in the DOM at all.

4

For the HTML you've given, this should work:

document.getElementById('obj1').getElementsByTagName('div')[0].getElementsByTagName('meta');

Just ignore the bogus id on the inner div and get it by tag name. You should also be able to ignore the inner div completely, since getElementsByTagName searches the entire subtree:

document.getElementById('obj1').getElementsByTagName('meta');
3
  • this will not work due to there being an unknown number of div's in the obj1 as well as the given Meta one
    – Supernovah
    Commented Mar 6, 2009 at 4:59
  • in that case you could still search through all the divs (recursively, even) until you find the <meta> tag you want. Since you can't change the HTML, you have to get creative with the DOM :)
    – rjh
    Commented Mar 6, 2009 at 14:05
  • You should still be able to look for the id "Meta" by looping through the child divs. You can't use getElementById because your html is invalid, but I'm guessing the div elements will still have their id values set. Commented Mar 6, 2009 at 20:44
3

As the id attribute is a unique document-wide identifier, you should probably namespace your ids.

<div id="obj1">
    <div id="obj1_Meta">
        <meta></meta>
    </div>
</div>

<div id="obj2">
    <div id="obj2_Meta">
        <meta></meta>
    </div>
</div>

document.getElementById('obj1_Meta').getElementsByTagName('meta')

Not the answer you're looking for? Browse other questions tagged or ask your own question.