jQuery nextAll — Click on h-element toggles all p-

2019-03-27 02:18发布

问题:

I'm creating an FAQ page where the answer is toggled by clicking on the question. The question is h3 and the answer is several p-elements. Like this:

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

How can I toggle all p-elements belonging to a certain question? My JS toggles all following p-elements on the page:

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

I cannot use div's or classes).

回答1:

The best way to do this is using each and iterating until you get to the next element that should stop the iteration. Returning false during an each stops the iteration. Using filter allows you to check the type of the element in the iteration and respond appropriately.

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


回答2:

I would do it this way:

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

Returning false from each() ends the chain.

I would also suggest, if possible, structuring your data better to handle this scenario. For example:

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

and then the problem becomes trivial to solve:

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


回答3:

Here is an interesting solution that doesn't use .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();

});

I'm looking for the next Ps by index. Not sure how practical this is, but it was a good exercise.



回答4:

I would recommend jQuery nextUntil();

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