37

折りたたみ可能な要素をページに動的に追加しています。Bootstrap は、「data-target」属性を使用して、折りたたみトグルが適用される要素を指定します。

ドキュメントから:

The data-target attribute accepts a css selector

親要素の次の兄弟を指定するセレクターを書く方法はありますか? ドキュメントの例はすべて、ID による選択を使用しているようです。

具体的には、HTML は次のようになります。

<div class="accordion-group">
<div class="accordion-heading">
  <a class="accordion-toggle" data-toggle="collapse" data-target="#collapseOne">
    Generated Title
  </a>
</div>
<div id="collapseOne" class="accordion-body collapse in">
  <div class="accordion-inner">
    Generated Content... this is big and sometimes needs collapsing
  </div>
</div>
</div>

次のようなものを書きたいと思います(jquery構文を違法に使用した疑似コード):

<a class="accordion-toggle" data-toggle="collapse" data-target="$(this).parent().next()">

しかし、これは CSS セレクターでは不可能かもしれないと考え始めています。

現在、回避策として、要素を作成するときに新しい ID (文字列に追加された増分番号) を生成しています。

セレクターを使用したより良いアプローチはありますか? data-target 属性を設定するには、作成後の JavaScript を使用する必要がありますか? 動的コンテンツの ID の生成は標準的なアプローチですか?

4

7 に答える 7

30

While it is true that the selector in a data-target attribute is a jQuery selector, the data-api specification for this plugin provides no means of referencing back to this in the scope of execution (see lines 147-153 in bootstrap-collapse.js for its use).

However, I would like to offer another alternative approach, which is to extend the data-api with your own custom toggle specifier. Let's call it collapse-next.

JS (see update note)

$('body').on('click.collapse-next.data-api', '[data-toggle=collapse-next]', function (e) {
  var $target = $(this).parent().next()
  $target.data('collapse') ? $target.collapse('toggle') : $target.collapse()
})

HTML

<a class="accordion-toggle" data-toggle="collapse-next">

JSFiddle (updated)

Downside here is that it's a rather tightly coupled approach, since the JS presumes a specific structure to the markup.


Note about IE issues

As @slhck pointed out in his answer, IE9 and under apparently fail on the first click when using an earlier revision of my answer. The cause is actually not an IE issue at all, but rather a Bootstrap one. If one invokes .collapse('toggle') on a target whose Carousel object is uninitialized, the toggle() method will be called twice - once during initialization and then again explicitly after initialization. This is definitely a Bootstrap bug and hopefully will get fixed. The only reason it doesn't appear as a problem in Chrome, FF, IE10, etc, is because they all support CSS transitions, and hence when the second call is made it short-circuits because the first one is still active. The updated workaround above merely avoids the double-call problem by checking for initialization first and handling it differently.

于 2012-10-09T23:18:55.713 に答える
5

@mervのソリューションは、IE9以下では機能しませんでした。これは、各アイテムを1回クリックしない限り、折りたたみ可能な状態を利用できないためです。ただし、Firefox と Chrome では問題なく動作しました。したがって、2 回クリックすると、すべてが機能します。

私がしたことは、.collapse-nextクラスをトリガー要素に設定し、ul兄弟をtoggleset toで強制的に折りたたむことでしたfalse:

$(".collapse-next").closest('li').each(function(){
  if ($(this).hasClass('active')) {
    // pop up active menu items
    $(this).children("ul").collapse('show');
  } else {
    // just make it collapsible but don't expand
    $(this).children("ul").collapse({ toggle: false });
  }
});

これは、メニューの状態を実際に切り替えるためのものです。

$('.collapse-next').click(function(e){
  e.preventDefault();
  $(this).parent().next().collapse('toggle');
});

属性を使用data-することは、やや現代的でクリーンなアプローチのようですが、クラスを操作する古いブラウザーの場合、jQuery も同様に機能するようです。

于 2013-03-21T14:59:58.493 に答える
1

最善の方法は、これをすべてのaccordion-toggle要素を反復処理しdata-target、jquery を介してそれらの属性を動的に設定し、その後、ブートストラップで言及されているアコーディオンのコードを配置することだと思います。

例 :

$(function(){
    $("a.accordion-toggle").each(function(index) {
        $(this).attr("data-target", "#" + $(this).parent().next().attr("id"));
    });

    // accoridon code
});

これが役立つことを願っています

于 2012-10-09T18:22:45.343 に答える
0

TYPO3 FCE と Bootstrap アコーディオン

私もこの問題で問題を抱えています。アコーディオンに無限の数の要素を追加できるようにしたい顧客のために TYPO3 で使用しています。そこで、フレキシブル コンテンツ エレメントを作成し、エレメントをマッピングしました。

その data-toggle="collapse-next" のアイデアは、開いている要素を閉じなかったため、期待どおりに機能しませんでした。ここでコードを見つけてください。うまくいけば、誰かが有用なものを見つけます。

Javascript

$(document).on('click.collapse-next.data-api', '[data-toggle=collapse-next]', function (e) {
  var $container = $(this).parents(".accordion");
  var $opencontainers = $container.find(".in");
  var $target = $(this).parent().next();
  $target.data('collapse') ? $target.collapse('toggle') : $target.collapse();
  $opencontainers.each(function() {$(this).collapse('toggle')});
})

HTML

<html>
    <div class="accordion">
        <div class="accordion-section">
            <div class="accordion-group">
                <div class="accordion-heading">
                    <a class="accordion-toggle" data-toggle="collapse-next">
                        Collapsible Group Item #1
                    </a>
                </div>
                <div class="accordion-body collapse">
                    <div class="accordion-inner">
                        Anim pariatur cliche...
                    </div>
                </div>
            </div>
        </div>
    </div>
</html>
于 2013-08-06T10:50:24.593 に答える
0

これは、一意の ID を必要とせず、特定の html 構造を回避するアプローチです。

これにより、折りたたみトリガーとターゲットの各インスタンスが html の「セクション」に含まれます。特に複数のインスタンスに対して、クラスセレクターを使用するのが好きです。この場合、人為的な一意の ID を作成する必要がなくなります。

@merv の優れた回答を借りて、 data-togglecollapse-sectionに彼のような名前を付けcollapse-next、 data-section 属性を追加しました。これは、parent().next() の代わりに、closest() セクション名を検索してから、指定されたターゲット名を検索します。彼らは兄弟または他のレベルである可能性があります。

(スタイリングとの混合を避けるために、jqueryセレクターとして使用されるクラス名のプレフィックスとして「id ...」を使用する命名規則があります。)

HTML

<div class="accordion-group idCollapseSection">
  <div class="accordion-heading">
    <a class="accordion-toggle" data-toggle="collapse-section"
       data-section=".idCollapseSection" data-target=".idCollapseTarget">
      Generated Title
    </a>
  </div>
  <div>Any other html, at various depths.
    <div class="accordion-body collapse in idCollapseTarget">
      <div class="accordion-inner">
        Generated Content... this is big and sometimes needs collapsing
      </div>
    </div>
  </div>
</div>

JS

//------------------------------
// Bootstrap Collapse.
//------------------------------
// Extend collapse to contain trigger and target within an enclosing section.
$('body').on('click.collapse-section.data-api', '[data-toggle=collapse-section]', function (e) {
  var thisTrigger = $(this);
  var sectionSelector = thisTrigger.data("section");
  var targetSelector = thisTrigger.data("target");
  var target = thisTrigger.closest(sectionSelector).find(targetSelector);
  target.data('bs.collapse') ? target.collapse('toggle') : target.collapse();
});
于 2017-09-03T02:47:06.920 に答える