99

How can I select the link elements of only the parent <ul> from a list like this?

<ul>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a>
  <ul>
    <li><a href="#">Link</a></li>
    <li><a href="#">Link</a></li>
    <li><a href="#">Link</a></li>
    <li><a href="#">Link</a></li>
    <li><a href="#">Link</a></li>
  </ul>
</li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>

So in css ul li a, but not ul li ul li a

Thanks

Paolo Bergantino
  • 480,997
  • 81
  • 517
  • 436
aston
  • 1,045
  • 1
  • 8
  • 6

11 Answers11

109
$("ul > li a")

But you would need to set a class on the root ul if you specifically want to target the outermost ul:

<ul class="rootlist">
...

Then it's:

$("ul.rootlist > li a")....

Another way of making sure you only have the root li elements:

$("ul > li a").not("ul li ul a")

It looks kludgy, but it should do the trick

Philippe Leybaert
  • 168,566
  • 31
  • 210
  • 223
  • Hmm I discovered my problem was with using jquery 1.2. I've replaced it with 1.3 and these kind of selectors are working fine now. Thanks very much for your reply and everyone who replied. – aston Jun 10 '09 at 20:33
  • In case you don't want to add a class just do $("ul:first > li a") obviously this would work only for the first level, not the inner levels. – Alfonso Sep 11 '13 at 15:18
  • 1
    Thank you for your tip. I have tested this too, and it seems it works well: `ul.find(">li");` if you have the "ul" node as JQuery object in ul variable. – John Boe Sep 28 '19 at 17:37
  • This answer is way too overrated. Out of all solutions here only the last one works as requested... – EvgenKo423 Mar 15 '23 at 06:08
61

Once you have the initial ul, you can use the children() method, which will only consider the immediate children of the element. As @activa points out, one way to easily select the root element is to give it a class or an id. The following assumes you have a root ul with id root.

$('ul#root').children('li');
tvanfosson
  • 524,688
  • 99
  • 697
  • 795
7

As stated in other answers, the simplest method is to uniquely identify the root element (by ID or class name) and use the direct descendent selector.

$('ul.topMenu > li > a')

However, I came across this question in search of a solution which would work on unnamed elements at varying depths of the DOM.

This can be achieved by checking each element, and ensuring it does not have a parent in the list of matched elements. Here is my solution, wrapped in a jQuery selector 'topmost'.

jQuery.extend(jQuery.expr[':'], {
  topmost: function (e, index, match, array) {
    for (var i = 0; i < array.length; i++) {
      if (array[i] !== false && $(e).parents().index(array[i]) >= 0) {
        return false;
      }
    }
    return true;
  }
});

Utilizing this, the solution to the original post is:

$('ul:topmost > li > a')

// Or, more simply:
$('li:topmost > a')

Complete jsFiddle available here.

Courtney Christensen
  • 9,165
  • 5
  • 47
  • 56
  • By using new DOM methods you can dramatically improve performance of `:topmost` - try using `.parentElement.closest(selector)`. As always, IE+Edge are the only ones not to support it >:-( so here's a polyfill http://pastebin.com/JNBk77Vm – oriadam Apr 19 '16 at 09:35
6

Simply you can use this..

$("ul li a").click(function() {
  $(this).parent().find(">ul")...Something;
}

See example : https://codepen.io/gmkhussain/pen/XzjgRE

GMKHussain
  • 3,342
  • 1
  • 21
  • 19
3

You might want to try this if results still flows down to children, in many cases JQuery will still apply to children.

$("ul.rootlist > li > a")

Using this method: E > F Matches any F element that is a child of an element E.

Tells JQuery to look only for explicit children. http://www.w3.org/TR/CSS2/selector.html

TitanKing
  • 31
  • 1
0

Try this:

$("#myId > UL > LI")
Lebnik
  • 628
  • 8
  • 11
0

I had some trouble with nested classes from any depth so I figured this out. It will select only the first level it encounters of a containing Jquery Object:

var $elementsAll = $("#container").find(".fooClass");4

var $levelOneElements = $elementsAll.not($elementsAll.children().find($elementsAll));

$levelOneElements.css({"color":"red"})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="fooClass" style="color:black">
Container
  <div id="container">
    <div class="fooClass" style="color:black">
      Level One
      <div>
        <div class="fooClass" style="color:black">
             Level Two
        </div>
      </div>
    </div>
    <div class="fooClass" style="color:black">
      Level One
      <div>
        <div class="fooClass" style="color:black">
             Level Two
        </div>
      </div>
    </div>
  </div>
</div>
Shawn Dotey
  • 616
  • 8
  • 11
0

1

 $("ul.rootlist > target-element")
2   $("ul.rootlist").find(target-element).eq(0) (only one instance)
3   $("ul.rootlist").children(target-element)

there are probably many other ways

atazmin
  • 4,757
  • 1
  • 32
  • 23
0

Use .querySelectorAll() with the descendant selector (>) and the :scope property: topParentElementUl.querySelectorAll(':scope > li > a')

You just need to modify some part for it to work with jQuery

reference: https://gomakethings.com/how-to-convert-the-jquery-children-method-to-vanilla-js/

0

You can also use $("ul li:first-child") to only get the direct children of the UL.

I agree though, you need an ID or something else to identify the main UL otherwise it will just select them all. If you had a div with an ID around the UL the easiest thing to do would be$("#someDiv > ul > li")

Chris Barr
  • 29,851
  • 23
  • 95
  • 135
  • 4
    This is incorrect usage of `:first-child`. This will select the "first `li` of every `ul`". The original post was asking for "every `li` from the first `ul`." – Courtney Christensen Jan 11 '12 at 15:14
-1
.add_to_cart >>> .form-item:eq(1)

the second .form-item at tree level child from the .add_to_cart

NullPoiиteя
  • 56,591
  • 22
  • 125
  • 143