开发者

Jquery - select immediate li text without selecting children ul's text

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:

  • First second-level element
  • Second second-level element
  • Third second-level element

Or all text from the third level... etc. That would allow me to list and count the items in a given开发者_Go百科 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);
});


If you want to select second li eg <li> Second second-level element, you can use the > child selector with eq like this:

$('ul#root > ul > li').eq(1)

For the third you set eq to 2 because its indexing starts from 0.

To loop over them, you can use the each like this:

$('ul#root > ul > li').eq(1).each(function(){
  alert($(this).text());
});

More Info:

  • Child Selector
  • .eq()


A more robust method is to use the traversal "contents" and select node with type of (3) which is the node type for a text child element in HTML. For example:

$('ul#root > li > ul > li > ul').children('li').contents().each(function () {
    if (this.nodeType == 3) alert(this.nodeValue);
});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜