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

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


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');

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 .


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


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


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

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>


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


-1
.add_to_cart >>> .form-item:eq(1)

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


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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.