¿Cómo puedo encontrar el hermano anterior más cercano con clase usando jQuery?

4 minutos de lectura

avatar de usuario
daulex

Aquí está el HTML aproximado con el que trabajo:

<li class="par_cat"></li>
<li class="sub_cat"></li>
<li class="sub_cat"></li>
<li class="par_cat"></li> // this is the single element I need to select
<li class="sub_cat"></li>
<li class="sub_cat"></li>
<li class="sub_cat current_sub"></li> // this is where I need to start searching
<li class="par_cat"></li>
<li class="sub_cat"></li>
<li class="par_cat"></li>

Necesito atravesar desde el .current_subencuentra el anterior más cercano .par_cat y hacerle cosas.

.find("li.par_cat") devuelve toda la carga de .par_cat (Tengo alrededor de 30 en la página). Necesito apuntar al único.

avatar de usuario
karim79

Probar:

$('li.current_sub').prevAll("li.par_cat:first");

Probado con su marcado:

$('li.current_sub').prevAll("li.par_cat:first").text("woohoo");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
  <li class="par_cat"></li>
  <li class="sub_cat"></li>
  <li class="sub_cat"></li>
  <li class="par_cat">// this is the single element I need to select</li>
  <li class="sub_cat"></li>
  <li class="sub_cat"></li>
  <li class="sub_cat current_sub">// this is where I need to start searching</li>
  <li class="par_cat"></li>
  <li class="sub_cat"></li>
  <li class="par_cat"></li>
</ul>

llenará el anterior más cercano li.par_cat con “woohoo”.

  • En realidad, después de un poco de mensajes de texto, el .prev() falló en algunos casos. .prevAll con :first, funcionó siempre. Gracias.

    – daulex

    22 de febrero de 2010 a las 11:13

  • .prev() solo verifica el elemento inmediatamente anterior. Agregué el comentario a la respuesta a continuación junto con el ejemplo de jsFiddle. Después de mirar alrededor, esta es la mejor respuesta, ya que aunque tiene que recorrer todos los elementos, no requiere dos funciones para capturar todo y luego filtrar para encontrarlo.

    – David Hobs

    27 de junio de 2012 a las 15:09

  • Esto significa :first está trabajando en una lista de elementos devueltos que comienza más cerca del objeto seleccionado (a diferencia de arriba hacia abajo en relación con la página)?

    – NReilingh

    10 de marzo de 2013 a las 0:41

  • Muchas gracias por la respuesta muy útil. ¿Puede responder la pregunta de @NReilingh porque realmente me confunde? no es :first un selector CSS que selecciona el primer elemento en DOM (p.ej div.red:first seleccionará el primer DIV rojo en el DOM) ¿jQuery analizó el selector de manera diferente?

    – Contador م

    26 de julio de 2017 a las 10:19

  • @Contadorم No hay un selector de CSS llamado :first.

    – TylerH

    22 oct 2020 a las 16:06

avatar de usuario
ed james

Probar

$('li.current_sub').prev('.par_cat').[do stuff];

  • ¿Esperar lo? ¿Esto no solo verifica el elemento inmediatamente anterior? ¿Entonces su código devolvería nulo? – Aquí se prueba en jsFiddle: jsfiddle.net/Y2TEH

    – David Hobs

    27 de junio de 2012 a las 15:05


  • @DavidHobs Escribí esto hace dos años… Ciertamente usaría prevAll() en estos días.

    –Ed James

    27 de junio de 2012 a las 16:29

  • @EdWoodcock considere actualizar su respuesta, en ese caso.

    usuario3714134

    10 de noviembre de 2015 a las 14:12

El uso de prevUntil() nos permitirá obtener un hermano lejano sin tener que obtener todos. Tenía un conjunto particularmente largo que requería demasiado CPU usando prevAll().

var category = $('li.current_sub').prev('li.par_cat');
if (category.length == 0){
  category = $('li.current_sub').prevUntil('li.par_cat').last().prev();
}
category.show();

Esto obtiene el primer hermano anterior si coincide, de lo contrario, obtiene el hermano anterior al que coincide, por lo que solo hacemos una copia de seguridad más con prev() para obtener el elemento deseado.

Creo que a todas las respuestas les falta algo. Prefiero usar algo como esto.

$('li.current_sub').prevUntil("li.par_cat").prev();

Le ahorra no agregar: primero dentro del selector y es más fácil de leer y comprender. El método prevUntil() también tiene un mejor rendimiento en lugar de usar prevAll()

Puedes seguir este código:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
    $(document).ready(function () {
        $(".add").on("click", function () {
            var v = $(this).closest(".division").find("input[name="roll"]").val();
            alert(v);
        });
    });
</script>
<?php

for ($i = 1; $i <= 5; $i++) {
    echo'<div class = "division">'
        . '<form method="POST" action="">'
        . '<p><input type="number" name="roll" placeholder="Enter Roll"></p>'
        . '<p><input type="button" class="add" name = "submit" value = "Click"></p>'
        . '</form></div>';
}
?>

Puedes hacerte una idea de esto.

¿Ha sido útil esta solución?