Bootstrap Accordion кнопка переключения "data-parent" не работает

Я пытаюсь создать аккордеон, используя Bootstrap 3, используя кнопку, складываемую с атрибутом data, без разметки аккордеона. Для меня это выглядит чище.

Однако я не могу заставить работать атрибут data-parent. Я хочу при открытии вопроса все остальные закрыть. Я читаю документы ( http://getbootstrap.com/javascript/), но все еще не могу заставить его работать.

Я использую следующий код:

<div class="accordion" id="myAccordion">
    <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">
    <p>Etiam posuere quam ac quam. Maecenas aliquet accumsan leo. Nullam dapibus fermentum ipsum. Etiam quis quam. Integer lacinia. Nulla est.</p>
    </div>
    <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">
    <p>Etiam posuere quam ac quam. Maecenas aliquet accumsan leo. Nullam dapibus fermentum ipsum. Etiam quis quam. Integer lacinia. Nulla est.</p>
    </div>
    <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">
    <p>Etiam posuere quam ac quam. Maecenas aliquet accumsan leo. Nullam dapibus fermentum ipsum. Etiam quis quam. Integer lacinia. Nulla est.</p>
    </div>
</div>

Вот JSFiddle: http://jsfiddle.net/twinsen/AEew4/

Я буду очень рад, если кто-то укажет мне, где я совершаю ошибку:\

7 ответов

Решение

Bootstrap 4

Использовать data-parent="" атрибут элемента свернуть (вместо элемента триггера)

<div id="accordion">
  <div class="card">
    <div class="card-header">
      <h5>
        <button class="btn btn-link" data-toggle="collapse" data-target="#collapseOne">
          Collapsible #1 trigger
        </button>
      </h5>
    </div>
    <div id="collapseOne" class="collapse show" data-parent="#accordion">
      <div class="card-body">
        Collapsible #1 element
      </div>
    </div>
  </div>
  ... (more cards/collapsibles inside #accordion parent)
</div>

Bootstrap 3

Смотрите эту проблему на GitHub: https://github.com/twbs/bootstrap/issues/10966

Существует "ошибка", которая делает аккордеон зависимым от .panel класс при использовании data-parent приписывать. Чтобы обойти это, вы можете обернуть каждую группу аккордеона в панель 'div'.

http://bootply.com/88288

<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, Тем не мение...

  • .panel должен быть прямым потомком элемента, используемого как data-parent=
  • каждый аккордеонный раздел (data-toggle=) должен быть прямым ребенком .panel ( http://www.bootply.com/AbiRW7BdD6)

Обратите внимание, что не только существует зависимость от.panel, она также зависит от структуры DOM.

Убедитесь, что ваши элементы структурированы так:

    <div id="parent-id">
        <div class="panel">
            <a data-toggle="collapse" data-target="#opt1" data-parent="#parent-id">Control</a>
                <div id="opt1" class="collapse">
...

Это в основном то, что сказал @Blazemonger, но я думаю, что иерархия целевого элемента тоже имеет значение. Я не закончил пробовать каждую возможность, но в основном это должно работать, если вы следуете этой иерархии.

К вашему сведению, у меня было больше слоев между control div и content div, и это не сработало.

Попробуй это. Простое решение без каких-либо зависимостей.

$('[data-toggle="collapse"]').click(function() {
  $('.collapse.in').collapse('hide')
});

Как сказал Blazemonger, #parent, .panel и.collapse должны быть прямыми потомками. Однако, если вы не можете изменить свой HTML, вы можете обойти его, используя события и методы начальной загрузки, с помощью следующего кода:

$('#your-parent .collapse').on('show.bs.collapse', function (e) {
    var actives = $('#your-parent').find('.in, .collapsing');
    actives.each( function (index, element) {
        $(element).collapse('hide');
    })
})

Если нашел это изменение к ответу Кшиштофа, то помог мой вопрос

$('#' + parentId + ' .collapse').on('show.bs.collapse', function (e) {            
    var all = $('#' + parentId).find('.collapse');
    var actives = $('#' + parentId).find('.in, .collapsing');
    all.each(function (index, element) {
      $(element).collapse('hide');
    })
    actives.each(function (index, element) {                
      $(element).collapse('show');                
    })
})    

если у вас есть вложенные панели, вам также может понадобиться указать, какие из них, добавив другое имя класса, чтобы различать их, и добавить это к селектору в приведенном выше JavaScript

Вот (надеюсь) универсальный патч, который я разработал, чтобы исправить эту проблему для BootStrap V3. Никаких особых требований, кроме подключения скрипта.

$(':not(.panel) > [data-toggle="collapse"][data-parent]').click(function() {
    var parent = $(this).data('parent');
    var items = $('[data-toggle="collapse"][data-parent="' + parent + '"]').not(this);
    items.each(function() {
        var target = $(this).data('target') || '#' + $(this).prop('href').split('#')[1];
        $(target).filter('.in').collapse('hide');
    });
});

РЕДАКТИРОВАТЬ: Ниже приведен упрощенный ответ, который все еще отвечает моим потребностям, и сейчас я использую делегированный обработчик кликов:

$(document.body).on('click', ':not(.panel) > [data-toggle="collapse"][data-parent]', function() {
    var parent = $(this).data('parent');
    var target = $(this).data('target') || $(this).prop('hash');
    $(parent).find('.collapse.in').not(target).collapse('hide');
});

У меня та же проблема при переключении аккордеона. Но когда я пытаюсь поместить блок скрипта в блок заголовка, это работает для моего случая!!

<head>   
...   
<link rel="stylesheet" href="../assets/css/bootstrap.css" />       
<script src="../assets/js/jquery-1.9.1.min.js" ></script>   
<script src="../assets/js/bootstrap.js" ></script> 
</head>
Другие вопросы по тегам