30

jQuery を使用して非常にわかりやすい FAQ ページを作成しています。そのようです:

<h2>What happens when you click on this question?</h2>
<p>This answer will appear!</p>

これはすべて非常に特殊な div 内にあるため、. でヘッダーを選択し$('#faq h2')ます。シンプルですね。H2 をクリックし、 を使用this.next()して次の段落を表示します。

(このページの警告は、非プログラマーがこのページを保守するということです。そのため、私はクラスを使用していません。新しいエントリに適切なクラスが含まれているという保証はありません。)

そう!問題:

<h2>What happens when you click on the next question?</h2>
<p>That is an interesting conundrum.</p>
<p>Because the maintainer is kind of long-winded</p>
<p>and many answers will span a few paragraphs.</p>

divでは、 s やクラスなどを追加せずに、this.next()クリックされた質問と次の質問 (H2 ヘッダー) の間のすべてをルーチンに選択させるにはどうすればよいでしょうか?

4

9 に答える 9

27

これは古い質問だと思いますが、jQuery1.4にはnextUntilがあります。したがって、このようなものが機能するはずです。

$('h2').click(function(){
    $(this).nextUntil('h2').show();
})
于 2010-02-06T22:49:45.673 に答える
21

興味深い問題です。最初に、答え全体を div で囲むのが最善の戦略だと思います。そうすれば、問題は簡単に解決できるようになります。

<h2>Question here</h2>
<div>
<p>Answer here</p>
</div>
</h2>Next Question</h2>
...

と:

$(function() {
  $("h2").click(function() {
    $(this).next().toggleClass("highlighted");
  });
});

しかし、そうは言っても、それがなくても解決可能です。

$(function() {
  $("h2").click(function() {
    $(this).nextAll().each(function() {
      if (this.tagName == 'H2') {
        return false; // stop execution
      }
      $(this).toggleClass("highlighted");
    });
  });
});

非常にエレガントではありませんが、うまくいきます。

注:これは、質問が兄弟であることを前提としています。そうでない場合は、はるかに複雑になります。

于 2009-05-14T13:48:29.003 に答える
7

css スタイルのDL リストを使用する方が理にかなっているでしょうか?

<dl class="faq">
    <dt>Question?</dt>
    <dd>
         <p>Answer</p>
         <p>Answer</p>
         <p>Answer</p>
    </dd>
</dl>

次に、次を使用して簡単に選択します。

$('+ dd', this); 

これが現在のdtの選択です。

または、意味的にも意味があるため、各回答を div でラップするだけです。ただし、意味的には DL リストの方がはるかに理にかなっていると思います。

于 2009-05-14T14:27:04.837 に答える
5

もちろん!whileループを作るだけです。

$('h2').click(function() {
    var next = $(this).next();
    while (next.length != 0 && next[0].nodeName == 'P')
    {
        next.toggle();
        next = next.next();
    }
});

これは、h2 の後に p タグしかないことを前提としています。img のようなものを追加したい場合は、while ループにさらに例外を追加できます。

または、H2 タグの間にあるものを気にしない場合は、H2 と等しくないことを確認できます。

$('h2').click(function() {
    var next = $(this).next();
    while (next.length != 0 && next[0].nodeName != 'H2')
    {
        next.toggle();
        next = next.next();
    }
});

これにより、次の H2 が見つかるか、DOM のレベルが上がるまで、クリックされた H2 の後のすべてが非表示になります。

于 2009-05-14T14:11:37.027 に答える
1

これに対する回答が必要な人がまだいる場合に備えて... これには、グループ内の h2 行も含まれます。

ここで、私のソリューションが機能するサンプル html の場合:

<h2> text1 </h2>
<p>asd</p>
<p>asd</p>
<p>asd</p>
<p>asd</p>
<h3>kjdf</h3>
<h2>asdk</h2>
<h3>kjdf</h3>
<p>asd</p>
<p>asd</p>
<p>asd</p>
<p>asd</p>
<h2>aqdsa</h2>

解決:

jQuery( function ( $ ) {
//defining groups for wrapping them in custom divs

    $('h2').each( function () {
        var grpForDiv= [];          
        var next = $(this).next();  
        grpForDiv.push(this);
        while ( next.length!==0 && next!== undefined && next[0].nodeName !== 'H2')
            {
            grpForDiv.push(next[0]);
            next = next.next();
            }       
        jQuery(grpForDiv).wrapAll('<div class="Group1" />');

    } );
} );
于 2013-10-27T04:58:15.163 に答える
1

これはあなたの質問への回答ではないかもしれませんが、すべての FAQ 項目 (つまり、すべての質問と回答のペア) を 1 つのDIV要素でラップすることができます。これは意味的に意味があり、ページを管理する非プログラマーは単に完全にコピーするDIV必要があります (クラスは必要ありません)。

HTML:

<div id="faq">
 <!-- start FAQ item -->
 <div>
  <h2>Question goes here</h2>
  <p>Answer goes here.</p>
  <p>And here.</p>
  <ul>
   <li>Really, use any HTML element you want here.</li>
   <li>It will work.</li>
  </ul>
 </div>
 <!-- end FAQ item -->
 <!-- start FAQ item -->
 <div>
  <h2>Second question goes here</h2>
  <p>Answer to question two.</p>
 </div>
 <!-- end FAQ item -->
</div>

JavaScript (jQuery):

$('#faq div h2').click(function() {
 $(this).parent().find(':not(h2)').show();
});
于 2009-05-14T13:39:16.810 に答える
0

選択された答えは良いものであることに注意してください。しかし、私は似たようなことをすることを検討しているので、残業しました:)

これを例に挙げました。

与えられた HTML:

<h2>Question 1</h2> 
<p>Answer 1</p> 
<p>Answer 1</p> 
<p>Answer 1</p> 
<h2>Question 2</h2> 
<p>Answer 2</p> 
<p>Answer 2</p> 
<p>Answer 2</p> 
<h2>Question 3</h2> 
<p>Answer 3</p> 
<p>Answer 3</p> 
<p>Answer 3</p> 

以下を実行すると、答えが得られます。これは、与えられたすべてのソリューションの中で最も洗練されたものだと思いますが、これに関する他の意見をかなり評価します。

jQuery.fn.nextUntilMatch = function(selector) { 
  var result = [];   
  for(var n=this.next();(n.length && (n.filter(selector).length == 0));n=n.next())  
      result.push(n[0]);   
  return $(result); 
} 

$(function() { 
  $('h2~p').hide(); 
  $('h2').click(function() { 
    $(this).nextUntilMatch(':not(p)').toggle(); 
  }) 
});
于 2009-05-14T16:24:14.073 に答える
0

HTML を編集せずにこれを行うこともできます。これは、この特定の目的のために作成したばかりのプラグインです。

(function($){
    $.fn.nextUntill = function(expr){
        var helpFunction = function($obj, expr){
            var $siblings = $obj.nextAll();
            var end = $siblings.index( $siblings.filter(expr) );
            if(end===-1) return $([]);
            return $siblings.slice(0, end);
        }
        var retObject = new Array();
        this.each(function(){
            $.merge(retObject, helpFunction($(this), expr));
        });
        return $(retObject);
    }
})(jQuery);

次のように使用できます。

 $('h2').click(function(){
    $(this).nextUntill('h2').show(); //this will show all P tags between the clicked h2 and the next h2 assuiming the p and h2 tags are siblings
 });
于 2009-05-14T17:26:45.887 に答える
-3

問題を解決するためのあなたの戦略が正しいとは思いません。あなたの問題を部分的に解決する6つの答えがありました.....

しかし、あなたの最大の問題は、メンテナーが div/spans/class などを使用することを信頼できないと言っていることです。

あなたがすべきことは、プロセスを簡素化し、あなたの方法を使用するように訓練することです。そうしないと、うまくいきません

独自の簡単なマークアップを追加して解釈します。

[Q] What happens when you click this link?[/Q]
[A] This marvellous answer appears [/A]

(jQuery は「ユーザー」のバグを修正しません)

于 2009-05-14T14:23:56.140 に答える