jQuery nextAll - щелчок по h-элементу переключает все p-элементы до следующего часа.

Я создаю страницу часто задаваемых вопросов, где можно переключать ответ, нажимая на вопрос. Вопрос в томh3 и ответ несколькоp-элементов. Как это:

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

Как я могу переключить всеp-элементы, принадлежащие к определенному вопросу? Мой JS переключает все следующиеp-элементы на странице:

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

Я не могу использоватьdivили классы).

Ответы на вопрос(4)

Вот интересное решение, которое не использует .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();

});

Я ищу следующие P по индексу. Не уверен, насколько это практично, но это было хорошее упражнение.

 03 июл. 2009 г., 21:53
Нет проблем! Я не предполагал, что это лучше - мне просто любопытно, можно ли это сделать без использования .each (). Хороший вопрос выше.
 03 июл. 2009 г., 19:19
ИМХО, этот код гораздо сложнее читать. Я предпочитаю принятый ответ.
 03 июл. 2009 г., 21:59
Да, запускал это через firebug с console.time и console.timeEnd, и даже с этим небольшим фрагментом html приведенный выше код работает плохо по сравнению с принятым ответом.
 03 июл. 2009 г., 19:32
По моим подсчетам это повторяет DOM три раза, чтобы избежать повторения элементов абзаца, следующих за одним заголовком один раз. Я голосую за не практично. :-)

Я бы сделал это так:

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

Возвращение false от каждого () завершает цепочку.

Я бы также предложил, если это возможно, структурировать ваши данные лучше, чтобы справиться с этим сценарием. Например:

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

и тогда проблема становится тривиальной для решения:

$(function() {
  $("div.answer").hide();
  $("h3.question").click(function() {
    $(this).next().toggle();
  });
});
 19 мая 2010 г., 04:09
+1 за чистую ссылку на jQuery, HTML, CSS и Seinfeld.
 03 июл. 2009 г., 22:14
cletus - это, вероятно, для вашей опечатки с nextall вместо nextAll и: вместо;
 03 июл. 2009 г., 18:11
Хотелось бы узнать причину понижения голосов ...
 03 июл. 2009 г., 18:04
Проверка tagName является хорошей идеей, мне не приходило в голову. Думаю, я застрял в jQuery-режиме. Возможно, вы захотите проверить его на предмет переключаемого элемента в случае, если есть что-то кроме абзаца, который не должен быть переключен.

Я бы посоветовалjQuery nextUntil ();

$(document).ready(function(){
    $("p").hide();
    $("h3").click(function(){
        $("h3").nextUntil("h3").toggle();
    });
});
Решение Вопроса

Лучший способ сделать это - использовать каждый итерацию, пока не дойдете до следующего элемента, который должен остановить итерацию. Возврат false во время каждого останавливает итерацию. Использование фильтра позволяет проверить тип элемента в итерации и ответить соответствующим образом.

$(function() {
   $("p").hide();
   $("h3").click(function() {
       $(this).nextAll().each( function() {
           if ($(this).filter('h3').length) {
              return false;
           }
           $(this).filter('p').toggle();
       });
   });
});
 03 июл. 2009 г., 19:21
Я думаю, что важно отметить, что этот код будет скрывать только теги абзаца. Если вы отправляете текст без тегов абзаца или каких-либо других тегов после тега h3, он не будет их скрывать.
 03 июл. 2009 г., 19:34
@Yogi - да, это по замыслу. Если вы хотите применить его к любым дочерним элементам, просто удалите «фильтр» («p») & quot; предшествующий тумблеру.
 Christoph03 июл. 2009 г., 18:12
Большое спасибо, работает отлично!
 03 июл. 2009 г., 18:14
Мне больше нравится ваше решение, так как оно более jQueriesh.

Ваш ответ на вопрос