Estoy creando una página de preguntas frecuentes donde la respuesta se alterna haciendo clic en la pregunta. La pregunta es h3 y la respuesta es varios p - elementos. Me gusta esto:

<h3>The First Question</h3>
<p>Answer Paragraph</p>
<p>Answer Paragraph</p>
<p>Answer Paragraph</p>

<h3>The Second Question</h3>
<p>Answer Paragraph</p>
<p>Answer Paragraph</p>

¿Cómo puedo alternar todos los elementos p que pertenecen a una determinada pregunta? Mi JS alterna todos los elementos p siguientes en la página:

$(document).ready(function(){
    $("p").hide();
    $("h3").click(function(){
        $(this).nextAll("p").toggle();
    });
});

No puedo usar div o clases).

8
Christoph 3 jul. 2009 a las 19:54

4 respuestas

La mejor respuesta

La mejor manera de hacer esto es usar cada uno e iterar hasta llegar al siguiente elemento que debería detener la iteración. Devolver falso durante cada uno detiene la iteración. El uso del filtro le permite verificar el tipo de elemento en la iteración y responder adecuadamente.

$(function() {
   $("p").hide();
   $("h3").click(function() {
       $(this).nextAll().each( function() {
           if ($(this).filter('h3').length) {
              return false;
           }
           $(this).filter('p').toggle();
       });
   });
});
16
tvanfosson 3 jul. 2009 a las 16:02

Aquí hay una solución interesante que no usa .each ()

$("h3").click(function() {

    var idx = $("h3,p").index(this);
    var nextIdx = ($("h3,p").index($(this).nextAll("h3")));
    var nextPs = (nextIdx == -1) ? $("h3,p").length - idx : nextIdx - idx;
    $(this).nextAll("p:lt(" + (nextPs - 1) + ")").toggle();

});

Estoy buscando la próxima P por índice. No estoy seguro de lo práctico que es esto, pero fue un buen ejercicio.

1
ScottE 3 jul. 2009 a las 17:16

Lo haría de esta manera:

$(function() {
  $("p").hide();
  $("h3").click(function() {
    $(this).nextAll().each(function() {
      if ($(this).is('h3')) {
        return false;
      }
      $(this).toggle();
    });
  });
});

Devolver falsa de cada () termina la cadena.

También sugeriría, si es posible, estructurar mejor sus datos para manejar este escenario. Por ejemplo:

<h3 class="question">Why is there no soup for me?</h3>
<div class="answer">
<p>...</p>
<p>...</p>
<p>...</p>
</div>

Y luego el problema se vuelve trivial de resolver:

$(function() {
  $("div.answer").hide();
  $("h3.question").click(function() {
    $(this).next().toggle();
  });
});
8
Paolo Bergantino 3 jul. 2009 a las 21:25

Recomendaría jQuery nextUntil ();

$(document).ready(function(){
    $("p").hide();
    $("h3").click(function(){
        $("h3").nextUntil("h3").toggle();
    });
});
0
Ilya 9 ene. 2015 a las 10:31