2009-07-03 7 views
8

Sto creando una pagina di domande frequenti in cui la risposta viene attivata facendo clic sulla domanda. La domanda è h3 e la risposta è più p -elementi. Come questo:jQuery nextAll - Fare clic su h-elemento attiva tutti gli elementi P fino al prossimo 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> 

Come posso attivare o disattivare tutti i p -Elementi appartenenti a una determinata domanda? Il mio JS alterna tutto seguendo p -Elementi sulla pagina:

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

non posso usare div 's o classi).

risposta

16

Il modo migliore per farlo è usare tutti e l'iterazione fino ad arrivare al successivo elemento che dovrebbe fermare l'iterazione. Restituendo false durante ciascuna interrompe l'iterazione. L'utilizzo del filtro consente di verificare il tipo dell'elemento nell'iterazione e rispondere in modo appropriato.

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

Grazie mille, funziona perfettamente! – Christoph

+1

Mi piace la tua soluzione migliore dato che è più jQueriesh. – SolutionYogi

+0

Penso che sia probabilmente importante notare che questo codice nasconderà solo i tag di paragrafo. Se testo senza tag di paragrafo o altri tag dopo il tag h3, non li nasconde. – SolutionYogi

8

Vorrei fare in questo modo:

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

Tornando falsa da ogni() termina la catena.

Vorrei anche suggerire, se possibile, di strutturare meglio i dati per gestire questo scenario. Per esempio:

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

e allora il problema diventa banale da risolvere:

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

Controllo della tagName è una buona idea, non si è verificato a me. Credo di essere stato bloccato in modalità jQuery. Si potrebbe voler controllare che l'elemento sia commutato anche nel caso in cui ci sia qualcosa di diverso da un paragrafo che non dovrebbe essere commutato. – tvanfosson

+0

Mi piacerebbe sapere il motivo del downvote ... – cletus

+0

cletus: probabilmente è per il tuo errore di battitura con nextall invece di nextAll e il: invece di; – ScottE

1

Ecco una soluzione interessante che non utilizza .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(); 

}); 

sto cercando per la prossima Ps in base all'indice. Non sono sicuro di quanto sia pratico, ma è stato un buon esercizio.

+0

IMHO, questo codice è molto più difficile da leggere. Preferisco la risposta accettata. – SolutionYogi

+0

Tramite il mio conteggio questo itera attraverso il DOM tre volte per evitare di iterare attraverso gli elementi del paragrafo che seguono una singola intestazione una volta. Io voto per non pratico. :-) – tvanfosson

+0

Nessun problema! Non stavo suggerendo che fosse meglio - ero solo curioso di poterlo fare senza usare .each(). Buon punto sopra. – ScottE

0

Vorrei raccomandare jQuery nextUntil();

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