I'm trying to take a structure of nested html unordered lists as a database for some information a need to organize and analyze. I'm trying to filter, count and present the information using jQuery. I'm striving for the lists not to have any class or id attribute, so that they are very clean. Only the root would have a class or id like this:
<ul id="root">
<li> First first-level element
<ul>
<li> First second-level element
<ul>
<li>First Third-level element</li>
<li>Second Third-level element</li>
</ul>
</li>
<li> Second second-level element
<ul>
<li>Third Third-level element</li>
<li>Fourth Third-level element</li>
</ul>
</li>
</ul>
</li>
<li> Second first-level element
<ul>
<li> Third second-level element
<ul>
<li>Fifth Third-level element</li>
</ul>
</li>
</ul>
</li>
</ul>
My question is: how can I select a li's immediate child text node without selecting text in that li's child and grandchild ul's (i.e. its sublists)? For example, given the html list above, I would like to be able to come up with a list of all text nodes in the second level:
Or all text from the third level... etc. That would allow me to list and count the items in a given level. The closest I've been is:
// to select items in second but not third level
$('ul#root ul').not('ul#root ul ul').children('li')
But it is not a flexible solution. What if the list has many levels, say seven? to select sixth level you would have to do something like:
// to select items in second but not third level
$('ul#root ul ul ul ul ul').not('ul#root ul ul ul ul ul ul').children('li')
There must be another way but I haven't found it. Any suggestions are much appreciated.
As stated here:
jQuery: Find the text of a list item that contains a nested ul
"Normal DOM methods allow to access text contents for just one element"
So this is one solution: This outputs third level elements one by one:
$('ul#root > li > ul > li > ul').children('li').each(function(){
alert($(this)[0].firstChild.textContent);
});
This outputs second level elements:
$('ul#root > li > ul').children('li').each(function(){
alert($(this)[0].firstChild.textContent);
});
This outputs first level elements:
$('ul#root').children('li').each(function(){
alert($(this)[0].firstChild.textContent);
});