4

I have some lists set up like the following:

<ul id="menu">
    <li>
        <a href="#">link a</a>
        <ul>
            <li>...</li>
            <li>...</li>
        </ul>
    </li>
    <li>
        <a href="#">link b</a>
        <ul>
            <li>...</li>
            <li>...</li>
        </ul>
    </li>
    <li>
        <a href="#">link c</a>
        <ul>
            <li>...</li>
            <li>...</li>
        </ul>
    </li>
</ul>

I'm trying to pull the text from each of the first anchors (link a, link b, link c), but am having some problems.

Most recently, I've tried:

var X = document.getElementById("menu");
var Y = X.getElementsByTagName("li");
for (var i = 0; i < Y.length; i++) {
    var Z = Y[i].getElementsByTagName('A');
    console.log(Z[0].innerHTML);
}

but this jumps into the <ul>s within the <li>s.

What I need really is to be able to get the <a> reference to the top level <li>s and also be able to grab the text within the <a> of those <li>s.

TylerH
  • 20,799
  • 66
  • 75
  • 101
RON2015
  • 443
  • 3
  • 16

3 Answers3

4

To get direct children of the ul#menu use children HTMLCollection:

var X = document.getElementById("menu").children;

Alternatively, you could select the same collection of li elements with querySelectorAll method using direct children selector:

var X = document.querySelectorAll("#menu > li");
dfsq
  • 191,768
  • 25
  • 236
  • 258
  • why would my code not return back the first one but return back all the rest? var children = document.querySelectorAll("#menu > li"); for(var i=0; i < children.length; i++){ console.log(children[i].firstChild.innerHTML); } – RON2015 Apr 05 '15 at 12:02
  • its coming back as undefined – RON2015 Apr 05 '15 at 12:04
  • @RON2015, please check example: http://jsfiddle.net/txmvshpa/1/ If i understand correctly - ''sub-link'' shouldn't be returned? The easiest way would be to add class to top level li's, and to target their class, if it is allowed.... :) – sinisake Apr 05 '15 at 12:08
  • @nevermind thank you but i do not want sub link returned, only link a, link b, link c – RON2015 Apr 05 '15 at 12:13
  • @RON2015 it's undefined because `firstChild` is a textNode (new line chracter or tab, space, etc.). You want `children[0].firstElementChild`. Or you can select `a` element all at once with `var a = document.querySelectorAll("#menu > li > a")`. – dfsq Apr 05 '15 at 12:19
  • @dfsq thank you, and thank everyone else who helped with this.. I hope this works in IE7, im using menu.children; instead of querySelectorAll because i saw on that compatability page that its not supported in IE7. will the way I am doing it work?? – RON2015 Apr 05 '15 at 12:29
  • @RON2015: why not try it and find out? – halfer Apr 05 '15 at 12:50
  • @RON2015 Yes, for IE7 compatibility you should use `children`. It should work for you well. – dfsq Apr 05 '15 at 17:17
  • It is working well, thank you for that, but there is another issue now... If you happen to see this comment, please take a look at the new question page I posted. Thanks again. http://stackoverflow.com/questions/29463048/getcomputedstyle-substitue-currentstyle-ie8-7-not-working – RON2015 Apr 05 '15 at 22:45
1

Why not using document.querySelectorAll for this. It is wide supported: http://caniuse.com/#feat=queryselector

And it is easy to query like in css style. Hope it help. Here is the documentation of how to use it: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll

Also can be interested in this for selecting single item: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector

var childNodes = document.querySelectorAll("#menu > li");
Rise Ledger
  • 949
  • 7
  • 11
0
var X = document.getElementById("menu");
var Y = X.getElementsByTagName("li");



for (var i = 0; i < Y.length; i++) {
 if(Y[i].parentNode.getAttribute('id')=='menu') {


   var Z = Y[i].getElementsByTagName('a');
   console.log(Z[0].innerHTML);

   }




}

Demo: http://jsfiddle.net/txmvshpa/3/

sinisake
  • 11,240
  • 2
  • 19
  • 27