jquery encuentra el hermano anterior más cercano con clase

146

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_sub, encontrar el anterior más cercano .par_caty hacerle cosas.

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

Realmente agradecería cualquier consejo :)

daulex
fuente
77
¡Guau, los gatos realmente están en Internet! Ahora tenemos gatos par y subgatos también.
JD Smith

Respuestas:

257

Tratar:

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

Probado con su marcado:

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

llenará el anterior más cercano li.par_catcon "woohoo".

karim79
fuente
gracias Karim Esto también funcionó bien, pero supongo que .prev () consumiría menos recursos, ya que .prevAll obtendría TODOS los elementos coincidentes anteriores y luego filtraría el que necesito. Aceptando la respuesta de Ed.
daulex
3
En realidad, después de un poco de mensajes de texto, el .prev () falló en algunos casos. .prevTodo con: primero, trabajado cada vez. Gracias.
daulex
1
.prev () solo verifica el elemento inmediatamente anterior. Agregué el comentario a la respuesta a continuación junto con el ejemplo 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 todos y luego filtrar para encontrarlos.
David Hobs
8
¿Esto significa que :firstestá trabajando en una lista de elementos devueltos que comienza más cerca del objeto seleccionado (en lugar de arriba a abajo en relación con la página)?
NReilingh
2
Muchas gracias por la muy útil respuesta. ¿Puedes responder a la pregunta de @NReilingh porque realmente me confunde? ¿No es :firstun selector CSS que selecciona el primer elemento en DOM (por ejemplo div.red:first, seleccionará el primer DIV rojo en el DOM ) jQuery analizó el selector de manera diferente?
Contador م
17

Tratar

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

Ed James
fuente
19
¿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
44
@DavidHobs Escribí esto hace dos años ... Ciertamente usaría prevAll () en estos días.
Ed James
8
@EdWoodcock considere actualizar su respuesta, en ese caso.
Hugo Zink
14

El uso de prevUntil () nos permitirá obtener un hermano distante sin tener que obtener todo. Tenía un conjunto particularmente largo que era demasiado intensivo de 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.

eprothro
fuente
5

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

Tom McDonough
fuente
0

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.

AL MaMun
fuente