Как вы заставляете Twitter Bootstrap Accordion держать одну группу открытой?

Я пытаюсь имитировать панель Outlook с помощью начальной загрузки Twitter с помощью плагина аккордеона и коллапса, пока у меня работает коллапс и аккордеон, но в настоящее время он позволяет свернуть все разделы.

Я хотел бы ограничить это так, чтобы всегда показывался один и только один.

Вот тот, над которым я работаю: http://jsfiddle.net/trajano/SMT9D/ и я думаю, что это где-то

$('#accordions').on('hide', function (event) {
  console.warn("HIDE TRIGGERED, check if trying to hide the active one if so stop");
})

12 ответов

Решение

Вот простой способ сделать это:

Новый Bootstrap 3

JsFiddle для Bootstrap 3.

Код для Bootstrap 3:

$('.panel-heading a').on('click',function(e){
    if($(this).parents('.panel').children('.panel-collapse').hasClass('in')){
        e.stopPropagation();
    }
    // You can also add preventDefault to remove the anchor behavior that makes
    // the page jump
    // e.preventDefault();
});

Код проверяет, является ли выбранный элемент тем, который отображается в данный момент (классом "in"), и если он имеет класс "in", он останавливает процесс сокрытия.


Устаревший Bootstrap 2

JsFiddle для Bootstrap 2.

Код для Bootstrap 2:

$('.accordion-toggle').on('click',function(e){
    if($(this).parents('.accordion-group').children('.accordion-body').hasClass('in')){
        e.stopPropagation();
    }
    // You can also add preventDefault to remove the anchor behavior that makes
    // the page jump
    // e.preventDefault();
});

Примечание: будьте осторожны, если вы хотите прикрепить больше событий щелчка на аккордеоне, так как e.stopPropagation() заблокирует события, которые произошли бы после проверки.

Обновлено 2018

Вот как сохранить как минимум открытость в Bootstrap v3 или v4. Это означает, что открытый аккордеон может быть закрыт только при переключении другого открытого.

Bootstrap 4

https://www.codeply.com/go/bbCcnl0jBB

// the current open accordion will not be able to close itself
$('[data-toggle="collapse"]').on('click',function(e){
    if ( $(this).parents('.accordion').find('.collapse.show') ){
        var idx = $(this).index('[data-toggle="collapse"]');
        if (idx == $('.collapse.show').index('.collapse')) {
            e.stopPropagation();
        }
    }
});

Также см. Этот ответ, в котором показано, как указать аккордеон "по умолчанию", который открывается, когда все остальные закрыты.


Bootstrap 3

$('[data-toggle="collapse"]').on('click',function(e){
    if($(this).parents('.panel').find('.collapse').hasClass('in')){
        var idx = $(this).index('[data-toggle="collapse"]');
        var idxShown = $('.collapse.in').index('.accordion-body');
        if (idx==idxShown) {
            e.stopPropagation();
        }
    }
});

https://www.codeply.com/go/yLw944BrgA

<div class="accordion" id="myAccordion">
    <div class="panel">
        <button type="button" class="btn btn-danger" data-toggle="collapse" data-target="#collapsible-1" data-parent="#myAccordion">Question 1?</button>
        <div id="collapsible-1" class="collapse">
            ..
        </div>
    </div>
    <div class="panel">
        <button type="button" class="btn btn-danger" data-toggle="collapse" data-target="#collapsible-2" data-parent="#myAccordion">Question 2?</button>
        <div id="collapsible-2" class="collapse">
            ..
        </div>
    </div>
    <div class="panel">
        <button type="button" class="btn btn-danger" data-toggle="collapse" data-target="#collapsible-3" data-parent="#myAccordion">Question 3?</button>
        <div id="collapsible-3" class="collapse">
           ...
        </div>
    </div>
</div>

(Примечание: panel класс необходим в Bootstrap 3, чтобы заставить работать поведение аккордеона)

Я хочу уточнить ответ @Hugo Dozois

http://jsfiddle.net/SMT9D/61/

Вы должны добавить e.preventDefault(); чтобы предотвратить поведение по умолчанию # HTML-якорь, если у вас есть свиток на вашей странице

$('.panel-heading a').on('click',function(e){
    if($(this).parents('.panel').children('.panel-collapse').hasClass('in')){
        e.preventDefault();
        e.stopPropagation();
    }
});

Или вы можете использовать простой трюк CSS следующим образом:

/*
prevent the active panel from collapsing
 */
.panel-group [aria-expanded=true]{
  /*
  http://caniuse.com/#feat=pointer-events
  Works for MOST modern browsers. (- Opera Mobile)
  */
  pointer-events: none;
}

должны иметь соответствующие теги на неактивных ссылках панели

 aria-expanded="false"

Поскольку все другие ответы JS используют нецелесообразный stopPropagation() здесь мое решение с использованием только собственных событий Bootstrap (протестировано на Bootstrap 4).

JsFiddle

$('#accordionExample').on('show.bs.collapse', function () {
    $(this).data('isShowing', true);
});

$('#accordionExample').on('hide.bs.collapse', function (event) {
    if (!$(this).data('isShowing')) {
        event.preventDefault();
    }

    $(this).data('isShowing', false);
});

Он использует тот факт, что нажатие на свернутый элемент приведет к show.bs.collapse с последующим hide.bs.collapse, Принимая во внимание, что щелчок на открытом элементе приведет только к hide.bs.collapse,

Ни одно из представленных решений не позволяет иметь более одного аккордеона на одной странице, сохраняя или не открывая одну вкладку.

Вот мое решение:

$("[data-toggle=buttons][data-oneopen=true] [data-toggle=collapse]").on("click", function (e) {
  var me = $(this);
  var target = $(me.attr("data-target") || me.attr("href"));
  if (target.hasClass("show")) {
    e.stopPropagation();
  }
});

Сначала я выбрал data-oneopen атрибут, чтобы пометить эти кнопки-гармошки, чтобы включить это поведение, но его можно заменить классом или любым другим селектором.

Потом проверяю data-target а также hrefатрибуты, чтобы найти соответствующую вкладку.

Наконец-то я stopPropagation если товар имеет show класс, просто замените его на in класс, чтобы иметь решение для Bootstrap 3.

Бутстрап 5

Опустить data-bs-parent атрибут на каждом .accordion-collapse чтобы элементы аккордеона оставались открытыми при открытии другого элемента.

Решение для Bootstrap-5

      $(this).on('mouseenter', function (e) {
    if( !$(this).hasClass('collapsed')) {
        $(this).attr('data-bs-toggle','disabled');
    }
})
$(this).on('mouseleave', function (e) {
    if( !$(this).hasClass('collapsed')) {
        $(this).attr('data-bs-toggle','collapse');
    }
})

Надеюсь, это поможет Андреасу

Bootstrap 4.0

$('.card').click(function(e) {
  if (
    $(this)
      .find('.collapse')
      .hasClass('show')
  ) {
    e.stopPropagation();
  }
});

Этот блок кода проверяет, свернута ли карта, на которую нажали (глядя на div с классом collapse). Когда карта в настоящее время showп прекращает распространение события.

У меня есть сценарий, который не соответствует ни одному опубликованному ответу: несколько аккордеонов на одной странице и некоторые другие складные компоненты, которые не являются аккордеонами (без data-parent атрибуты).

$("[data-toggle=collapse][data-parent]").click(function (e) {
    var button = $(this);
    var parent = $(button.attr("data-parent"));
    var panel = parent.find(button.attr("href") || button.attr("data-target"));
    if (panel.hasClass("in")) {
        e.preventDefault();
        e.stopPropagation()
    }
});

Этот код срабатывает только на аккордеонах, так как проверяет data-parent приписывать. Это также не предполагает card (или же panel для структуры начальной загрузки 3), он использует те же атрибуты, что и интерфейс начальной загрузки.

Я надеюсь, что это помогает.

Начальная загрузка 5

Альтернативное решение от @awant. На этот раз, используя события коллапса, чтобы отключить кнопку. Это прекрасно работает с сенсорными экранами.

      $(this).on('show.bs.collapse', function (e) {
  $(buttonSelector).attr('data-bs-toggle','disabled');
})
$(this).on('hide.bs.collapse', function (e) {
  $(buttonSelector).attr('data-bs-toggle','collapse');
})

Согласно версии bootstarp 3.3.6, просто следуйте структуре

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">

<div class="panel-group" id="accordion" role="tablist"   aria-multiselectable="true">

  <div class="panel panel-default">
    <div class="panel-heading" role="tab" id="headingOne">
      <h4 class="panel-title">
        <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
          Collapsible Group Item #1
        </a>
      </h4>
    </div>
    <div id="collapseOne" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingOne">
      <div class="panel-body">
        collopse 1 body  here 
      </div>
    </div>
  </div>

  <div class="panel panel-default">
    <div class="panel-heading" role="tab" id="headingTwo">
      <h4 class="panel-title">
        <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
          Collapsible Group Item #2
        </a>
      </h4>
    </div>
    <div id="collapseTwo" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingTwo">
      <div class="panel-body">
        collapse body 2
      </div>
    </div>
  </div>

</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>

Другие вопросы по тегам