2

I'm attempting to target specific top level list items with jQuery. However some of these list items also include nested lists of their own,which I want to ignore.

I found a stackoverflow question here Target first level <li>s and not the nested <li>s about this very topic but after enacting the solutions I'm still encountering the same issue.

HTML:

<div>
  <ul>
    <li data-level="1">
      Upper List Item
      <ul>
        <li>Sub list item</li>
      </ul>
    </li>
    <li data-level="1">List item 2</li>
  </ul>
</div>

Javascript:

$(document).ready(function() {
    $("div > ul > li[data-level=1]").each(function(index){
    console.log(index + ":" + $(this).text());
  });
});

https://jsfiddle.net/o4mw0gd8/3/

Community
  • 1
  • 1
Matt
  • 896
  • 5
  • 18
  • 47

4 Answers4

2

The problem is that you are grabbing all text from inside the top level <li>'s.

Considering that sub-level <li>'s are inside of a top-level <li>, then the text of those is inside the top level <li>'s too...

Solution 1:

You should put your text inside a <span> tag and it would be much easier to find the text inside those <span>/s inside top-level <li>'s!

Solution 2:

Before grabbing the text of your <li>'s delete all <ul> elements inside it, so you would get only the text of the top level <li>'s

JS:

$("ul > li[data-level=1]").each(function(index) {
    var current = $(this).clone();
    current.find('ul').remove();
    console.log(index + ":" + current.text().trim() );
});

Working Fiddle

Aramil Rey
  • 3,387
  • 1
  • 19
  • 30
  • 1
    I don't have access to the actual content that's being produced (partially why I'm using jQuery in the first place to grab the list) which is why I can't really use solution 1. But solution 2 worked great! – Matt Dec 22 '15 at 14:42
1

Some tricks.

$("div > ul > li[data-level=1]").each(function(index){
    console.log(this.childNodes.item(0).textContent);
});
user5698801
  • 576
  • 4
  • 10
1

You can exclude child ul elements from selection using jquery .not():

$(document).ready(function() {
  $("ul > li[data-level=1]").each(function(index) {
     $(this).not("ul").css("color", "red");
  });
});
ul li {
  color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
  <li data-level="1">
    Upper List Item
    <ul>
      <li>Sub list item</li>
    </ul>
  </li>
  <li data-level="1">List item 2</li>
</ul>
Alex Char
  • 32,879
  • 9
  • 49
  • 70
0

As Aramil says - you taking the whole inner content, which include the nested ul>li:

 "Upper List Item
  <ul>
    <li>Sub list item</li>
  </ul>"

Bu you can solve it with substring like this:

 $(function(){
  $("li[data-level=1]").each(function(){
     var txt=this.innerHTML;//the whole text including the nested ul>li
      if(txt.indexOf("<")>-1)txt=txt.substring(txt.indexOf("<"),0);//cut from first tag if needed
     console.info(txt);//needed txt
   });
});
Nikita Kurtin
  • 5,889
  • 4
  • 44
  • 48