Sélection uniquement des éléments de premier niveau dans jquery

93

Comment puis-je sélectionner les éléments de lien du parent uniquement <ul>dans une liste comme celle-ci?

<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>

Donc en css ul li a, mais pasul li ul li a

Merci

Aston
la source

Réponses:

108
$("ul > li a")

Mais vous devrez définir une classe sur la racine ul si vous souhaitez spécifiquement cibler l'ul le plus externe:

<ul class="rootlist">
...

Alors c'est:

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

Une autre façon de vous assurer que vous n'avez que les éléments root li:

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

Ça a l'air kludgy, mais ça devrait faire l'affaire

Philippe Leybaert
la source
Hmm, j'ai découvert que mon problème était d'utiliser jquery 1.2. Je l'ai remplacé par 1.3 et ces types de sélecteurs fonctionnent bien maintenant. Merci beaucoup pour votre réponse et tous ceux qui ont répondu.
aston
Au cas où vous ne voudriez pas ajouter une classe, faites simplement $ ("ul: first> li a") évidemment cela ne fonctionnerait que pour le premier niveau, pas pour les niveaux internes.
Alfonso du
Merci pour votre conseil. J'ai testé cela aussi, et il semble que cela fonctionne bien: ul.find(">li");si vous avez le nœud "ul" comme objet JQuery dans la variable ul.
John Boe
55

Une fois que vous avez l'ul initial, vous pouvez utiliser la méthode children () , qui ne prendra en compte que les enfants immédiats de l'élément. Comme le souligne @activa, une façon de sélectionner facilement l'élément racine est de lui donner une classe ou un identifiant. Ce qui suit suppose que vous avez une racine ul avec id root.

$('ul#root').children('li');
Tvanfosson
la source
2
Merci, c'est très utile pour moi. Un $('ul').first().children('li')peut également être utilisé
Ivan Black
C'est la réponse préférée pour moi, car j'ai déjà l'élément et utiliserai donc .children au lieu de .find.
Herbert Van-Vliet
7

Comme indiqué dans d'autres réponses, la méthode la plus simple consiste à identifier de manière unique l'élément racine (par ID ou nom de classe) et à utiliser le sélecteur descendant direct.

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

Cependant, je suis tombé sur cette question à la recherche d'une solution qui fonctionnerait sur des éléments sans nom à des profondeurs variables du DOM.

Cela peut être réalisé en vérifiant chaque élément et en s'assurant qu'il n'a pas de parent dans la liste des éléments correspondants. Voici ma solution , enveloppée dans un sélecteur jQuery '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;
  }
});

En utilisant cela, la solution au message d'origine est:

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

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

JsFiddle complet disponible ici .

Courtney Christensen
la source
En utilisant de nouvelles méthodes DOM, vous pouvez considérablement améliorer les performances de :topmost- essayez d'utiliser .parentElement.closest(selector). Comme toujours, IE + Edge sont les seuls à ne pas le supporter> :-( alors voici un polyfill pastebin.com/JNBk77Vm
oriadam
3

Vous voudrez peut-être essayer ceci si les résultats sont toujours transmis aux enfants, dans de nombreux cas, JQuery s'appliquera toujours aux enfants.

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

En utilisant cette méthode: E> F Correspond à tout élément F qui est un enfant d'un élément E.

Indique à JQuery de rechercher uniquement les enfants explicites. http://www.w3.org/TR/CSS2/selector.html

TitanKing
la source
0

Vous pouvez aussi utiliser $("ul li:first-child") pour obtenir uniquement les enfants directs de l'UL.

Je suis d'accord cependant, vous avez besoin d'un identifiant ou de quelque chose d'autre pour identifier l'UL principale, sinon il les sélectionnera tous. Si vous aviez un div avec un identifiant autour de l'UL, la chose la plus simple à faire serait$("#someDiv > ul > li")

CBarr
la source
3
Il s'agit d'une utilisation incorrecte de :first-child. Cela sélectionnera le "premier lide chaque ul". Le message original demandait «tous liles premiers ul».
Courtney Christensen
0

Essaye ça:

$("#myId > UL > LI")
Lebnik
la source
0

J'ai eu des problèmes avec les classes imbriquées de n'importe quelle profondeur, alors j'ai compris. Il ne sélectionnera que le premier niveau qu'il rencontre d'un objet Jquery contenant:

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
la source
0

1

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

il y a probablement de nombreuses autres façons

Arlan T
la source
-1
.add_to_cart >>> .form-item:eq(1)

le deuxième .form-item au niveau de l'arborescence enfant du .add_to_cart

Isidoro
la source
1
Cela n'a même pas de sens pour la question
renke
>>> Qu'est-ce que c'est? Ce sélecteur a-t-il un nom? Est-ce même un sélecteur valide? Ou était-ce une blague?
John Boe