2009-07-03 7 views
8

Je crée une page FAQ où la réponse est permutée en cliquant sur la question. La question est h3 et la réponse est plusieurs p -elements. Comme ceci:jQuery nextAll - Cliquez sur l'élément h pour basculer tous les éléments p jusqu'à la prochaine h

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

Comment puis-je basculer tous les p -elements appartenant à une certaine question? Mon JS désélectionne tous suivant p -elements sur la page:

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

Je ne peux pas utiliser div « s ou des classes).

Répondre

16

La meilleure façon de le faire est d'utiliser chacun et itérer jusqu'à ce que vous obtenez à l'autre élément qui devrait arrêter l'itération. Renvoyer false pendant un chaque arrête l'itération. L'utilisation du filtre vous permet de vérifier le type de l'élément dans l'itération et de répondre de manière appropriée.

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

Merci beaucoup, fonctionne parfaitement! – Christoph

+1

J'aime mieux votre solution car elle est plus jQueriesh. – SolutionYogi

+0

Je pense qu'il est probablement important de noter que ce code ne cachera que les balises de paragraphe. Si vous textez sans balises de paragraphe ou d'autres balises après votre balise h3, il ne les cachera pas. – SolutionYogi

8

je le ferais de cette façon:

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

renvoie false each() termine la chaîne.

Je suggère également, si possible, de mieux structurer vos données pour gérer ce scénario. Par exemple:

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

et le problème devient trivial à résoudre:

$(function() { 
    $("div.answer").hide(); 
    $("h3.question").click(function() { 
    $(this).next().toggle(); 
    }); 
}); 
+0

Vérification de la tagName est une bonne idée, ne se produit pas pour moi. Je suppose que j'étais coincé en mode jQuery. Vous pouvez également vérifier si l'élément est basculé au cas où il y aurait autre chose qu'un paragraphe qui ne devrait pas être activé. – tvanfosson

+0

Aimerait connaître la raison de la downvote ... – cletus

+0

cletus - c'est probablement pour votre faute de frappe avec nextall au lieu de nextAll et le: au lieu de; – ScottE

1

Voici une solution intéressante qui n'utilise pas .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(); 

}); 

Je suis à la recherche de la prochaine Ps par index. Je ne sais pas à quel point c'est pratique, mais c'était un bon exercice.

+0

À mon humble avis, ce code est beaucoup plus difficile à lire. Je préfère la réponse acceptée. – SolutionYogi

+0

D'après mon compte, cela se répète à travers le DOM trois fois pour éviter d'itérer à travers les éléments de paragraphe après un seul en-tête. Je vote pour pas pratique. :-) – tvanfosson

+0

Pas de problème! Je ne disais pas que c'était mieux - j'étais juste curieux de savoir si cela pouvait être fait sans utiliser .each(). Bon point ci-dessus. – ScottE

0

Je recommande jQuery nextUntil();

$(document).ready(function(){ 
    $("p").hide(); 
    $("h3").click(function(){ 
     $("h3").nextUntil("h3").toggle(); 
    }); 
}); 
Questions connexes