Seleccionar solo elementos de primer nivel en jquery

93

¿Cómo puedo seleccionar los elementos de enlace solo del padre <ul>de una lista como esta?

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

Entonces en CSS ul li a, pero noul li ul li a

Gracias

Aston
fuente

Respuestas:

108
$("ul > li a")

Pero necesitaría establecer una clase en la raíz ul si desea apuntar específicamente al ul más externo:

<ul class="rootlist">
...

Entonces es:

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

Otra forma de asegurarse de que solo tiene los elementos raíz li:

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

Parece tonto, pero debería funcionar

Philippe Leybaert
fuente
Hmm, descubrí que mi problema era usar jquery 1.2. Lo reemplacé con 1.3 y este tipo de selectores funcionan bien ahora. Muchas gracias por su respuesta y por todos los que respondieron.
Aston
En caso de que no desee agregar una clase, simplemente haga $ ("ul: primero> li a") obviamente esto funcionaría solo para el primer nivel, no para los niveles internos.
Alfonso
Gracias por tu consejo. También he probado esto, y parece que funciona bien: ul.find(">li");si tiene el nodo "ul" como objeto JQuery en la variable ul.
John Boe
55

Una vez que tenga el ul inicial, puede usar el método children () , que solo considerará los hijos inmediatos del elemento. Como señala @activa, una forma de seleccionar fácilmente el elemento raíz es darle una clase o una identificación. Lo siguiente asume que tiene una raíz ul con id root.

$('ul#root').children('li');
tvanfosson
fuente
2
Gracias, es muy útil para mí. Una $('ul').first().children('li')también puede ser utilizado
Iván Negro
Esta es la respuesta preferida para mí, ya que ya tengo el elemento y, por lo tanto, usaré .children en lugar de .find.
Herbert Van-Vliet
7

Como se indica en otras respuestas, el método más simple es identificar de forma única el elemento raíz (por ID o nombre de clase) y usar el selector de descendientes directos.

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

Sin embargo, me encontré con esta pregunta en busca de una solución que funcione en elementos sin nombre en diferentes profundidades del DOM.

Esto se puede lograr marcando cada elemento y asegurándose de que no tenga un padre en la lista de elementos coincidentes. Aquí está mi solución , envuelta en un selector de jQuery 'superior'.

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

Utilizando esto, la solución a la publicación original es:

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

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

JsFiddle completo disponible aquí .

Courtney Christensen
fuente
Al utilizar nuevos métodos DOM, puede mejorar drásticamente el rendimiento de :topmost: intente utilizar .parentElement.closest(selector). Como siempre, IE + Edge son los únicos que no lo admiten> :-( así que aquí hay un polyfill pastebin.com/JNBk77Vm
oriadam
3

Es posible que desee probar esto si los resultados aún fluyen hacia los niños; en muchos casos, JQuery aún se aplicará a los niños.

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

Usando este método: E> F Coincide con cualquier elemento F que sea hijo de un elemento E.

Le dice a JQuery que busque solo niños explícitos. http://www.w3.org/TR/CSS2/selector.html

TitanKing
fuente
0

También puede usar $("ul li:first-child")para obtener solo los hijos directos de UL.

Sin embargo, estoy de acuerdo, necesita una identificación o algo más para identificar el UL principal, de lo contrario, simplemente los seleccionará todos. Si tuvieras un div con una ID alrededor de UL, lo más fácil sería$("#someDiv > ul > li")

CBarr
fuente
3
Este es un uso incorrecto de :first-child. Esto seleccionará el "primero lide cada ul". La publicación original pedía "todos lidesde el principio ul".
Courtney Christensen
0

Prueba esto:

$("#myId > UL > LI")
Lebnik
fuente
0

Tuve algunos problemas con las clases anidadas de cualquier profundidad, así que descubrí esto. Seleccionará solo el primer nivel que encuentre de un objeto Jquery contenedor:

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

1

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

probablemente hay muchas otras formas

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

el segundo .form-item a nivel de árbol hijo de .add_to_cart

isidoro
fuente
1
Esto ni siquiera tiene sentido para la pregunta
renke
>>> ¿Qué es eso? ¿Este selector tiene un nombre? ¿Es siquiera un selector válido? ¿O fue una broma?
John Boe