Bootstrap Collapse и его использование для создания аккордеона

Bootstrap Collapse и его использование для создания аккордеона
Содержание:
  1. Компонент Collapse
  2. Управление collapse-элементом через JavaScript
  3. Горизонтальный режим
  4. Методы компонента Collapse
  5. События компонента Collapse
  6. Аккордеон
  7. Комментарии

В этой статье познакомимся с компонентом Collapse, который предназначен для плавного сворачивания и разворачивания контента. А также его использование для создания аккордеона.

Компонент Collapse

Collapse – это компонент, который написан на JavaScript и предназначен для плавного сворачивания и разворачивания содержимого элемента.

Демонстрация работы Bootstrap Collapse

Обычно данное действие происходит при нажатии на какой-либо элемент, например <a> или <button>.

Привязка этого действия к элементу выполняется посредством добавления к нему следующих data-атрибутов:

  • data-bs-toggle="collapse";
  • data-bs-target="#target" или href="#target" (#target - это селектор того элемента, видимостью контента которого нужно управлять, т.е. сворачивать или разворачивать его).

Например:

Компонент Bootstrap Collapse
HTML
<!-- Bootstrap v5 -->
<!-- Ссылка для переключения видимости #target -->
<a class="btn btn-primary" data-bs-toggle="collapse" href="#target">Collapse</a>
<a class="btn btn-secondary" data-bs-toggle="collapse" href="#" data-bs-target="#target">Collapse</a>
<!-- Кнопка для переключения видимости #target -->
<button class="btn btn-success" type="button" data-bs-toggle="collapse" data-bs-target="#target">Collapse</button>

<!-- #target -->
<div class="collapse" id="target">
  <div class="card card-body">...</div>
</div>

В Bootstrap v4 или v3 атрибуты data-bs-toggle и data-bs-target указываются без -bs:

HTML
<!-- Bootstrap v4 -->
<!-- Ссылка для переключения видимости #target -->
<a class="btn btn-primary" data-toggle="collapse" href="#target">Collapse</a>
<a class="btn btn-secondary" data-toggle="collapse" href="#" data-target="#target">Collapse</a>
<!-- Кнопка для переключения видимости #target -->
<button class="btn btn-success" type="button" data-toggle="collapse" data-target="#target">Collapse</button>

<!-- #target -->
<div class="collapse" id="target">
  <div class="card card-body">...</div>
</div>

Если в data-bs-target (в Bootstrap v3 или v4: data-target) или href указать в качестве селектора, например, класс, то данный элемент при нажатии на него будет одновременно переключать видимость несколько элементов, имеющих него.

Использование Bootstrap Collapse для переключения видимости нескольких элементов
HTML
<!-- Bootstrap v5 -->
<!-- Ссылка для переключения видимости .target -->
<a class="btn btn-primary" data-bs-toggle="collapse" href="#" data-bs-target=".target">collapse all</a>
<!-- Ссылка для переключения видимости #target-1 -->
<a class="btn btn-secondary" data-bs-toggle="collapse" href="#" data-bs-target="#target-1">collapse #target-1</a>
<!-- Ссылка для переключения видимости #target-2 -->
<a class="btn btn-success" data-bs-toggle="collapse" href="#" data-bs-target="#target-2">collapse #target-2</a>

<!-- #target-1 -->
<div class="collapse target" id="target-1">
  <div class="card card-body">...</div>
</div>
<!-- #target-2 -->
<div class="collapse target" id="target-2">
  <div class="card card-body">...</div>
</div>

Сворачивание и разворачивание элемента выполняется с анимацией: значение height изменяется от текущего значения до 0 или наоборот. Учитывая, как CSS обрабатывает анимацию, вы не можете использовать padding для элемента .collapse. Данный элемент следует использовать как обёртку.

Компонент Collapse использует несколько классов:

  • collapse – контент скрыт;
  • collapse и show – контент отображается (при одновременной установке этих двух классов);
  • collapsing – добавляется, когда переход начинается, и удаляется, когда он заканчивается.

Если вы хотите чтобы collapse-элемент по умолчанию был открыт, то дополнительно добавьте к нему класс show:

HTML
<!-- collapse-элемент -->
<div class="collapse show" id="target">
  <div class="card card-body">...</div>
</div>

Управление collapse-элементом через JavaScript

Кроме привязки элементов через data-атрибуты, управлять видимостью collapse-элементов можно также с помощью JavaScript.

Пример переключения отображения #target при нажатии на #btn-target с помощью JavaScript:

Переключение отображения collapse-элемента с помощью JavaScript
HTML
<!-- Bootstrap v5 -->
<!-- Ссылка для переключения видимости #target -->
<a class="btn btn-primary" id="btn-target">Collapse</a>

<!-- #target -->
<div class="collapse" id="target">
  <div class="card card-body">...</div>
</div>

<script>
  const collapseElem = document.querySelector('#target');
  const collapse = new bootstrap.Collapse(collapseElem, {toggle: false});
  document.querySelector('#btn-target').addEventListener('click', (e) => {
    e.preventDefault();
    // сворачиваем или разворачиваем collapse-элемент
    collapse.toggle();
  });
</script>

Этот пример на Bootstrap 4:

HTML
<!-- Bootstrap v4 -->
<!-- Ссылка для переключения видимости #target -->
<a class="btn btn-primary" id="btn-target">Collapse</a>

<!-- #target -->
<div class="collapse" id="target">
  <div class="card card-body">...</div>
</div>

<script>
$('#btn-target').click((e) => {
  e.preventDefault();
  // сворачиваем или разворачиваем collapse-элемент
  $('#target').collapse('toggle');
});
</script>

При активировании контента в качестве collapse-элемента мы можем передать аргументы:

JavaScript
// Bootstrap v5
const collapseElem = document.querySelector('#target');
const collapse = new bootstrap.Collapse(collapseElem, {
  parent: false,
  toggle: true
});

// Bootstrap v4
$('#target').collapse({
  parent: false,
  toggle: true
})

Параметр parent (значение по умолчанию false) позволяет указать родитель. В этом случае при открытии collapse-элемента, все остальные, находящиеся внутри него, будут автоматически закрываться.

Пример Bootstrap Collapse с использованием параметра parent
HTML
<!-- Bootstrap v5 -->
<!-- Ссылки для переключения видимости collapse-элементов -->
<a class="btn btn-primary btn-target" data-target="#target-1">#target-1</a>
<a class="btn btn-primary btn-target" data-target="#target-2">#target-2</a>
<a class="btn btn-primary btn-target" data-target="#target-3">#target-3</a>

<!-- #target-1, #target-2, #target-3 -->
<div id="target-container">
  <div class="row">
    <div class="col">
      <div class="collapse" id="target-1">
        <div class="card card-body">...</div>
      </div>
    </div>
    <div class="col">
      <div class="collapse" id="target-2">
        <div class="card card-body">...</div>
      </div>
    </div>
    <div class="col">
      <div class="collapse" id="target-3">
        <div class="card card-body">...</div>
      </div>
    </div>
  </div>
</div>

<script>
const collapseElements = document.querySelectorAll('#target-container .collapse');
collapseElements.forEach(collapseEl => {
  new bootstrap.Collapse(collapseEl, { toggle: false, parent: '#target-container' });
})
document.addEventListener('click', (e) => {
  if (!e.target.dataset.target) {
    return;
  }
  const collapseElement = document.querySelector(e.target.dataset.target);
  const collapse = bootstrap.Collapse.getInstance(collapseElement);
  collapse.toggle();
});
</script>

Этот пример на Bootstrap 4: открыть

Параметр toggle (значение по умолчанию true) позволяет установить необходимо ли переключать collapse-элемент при инициализации.

Эти параметры также можно установить с помощью data-атрибутов. Для этого добавьте перед именем параметра data-. Например: data-parent="#target-container", data-toggle="false".

HTML
<div class="collapse" data-parent="#target-container" id="target-1">
  ...
</div>

Горизонтальный режим

В Bootstrap 5 компонент Collapse также поддерживает горизонтальный режим сворачивания и разворачивания контента. Осуществляется это посредством добавления класса collapse-horizontal и указания ширины для элемента, непосредственного содержащего контент.

Пример Bootstrap Collapse, который сворачивает и разворачивает контент в горизонтальном направлении
HTML
<!-- Bootstrap v5 -->
<!-- toggle #collapse -->
<a class="btn btn-primary" data-bs-toggle="collapse" href="#collapse">Collapse</a>
<!-- #collapse с классом collapse-horizontal -->
<div class="collapse collapse-horizontal" id="collapse">
  <!-- ширина: 300px -->
  <div class="card card-body" style="width: 300px;">...</div>
</div>

Методы компонента Collapse

Компонент Collapse имеет следующие методы:

  • toggle – скрывает или отображает контент;
  • show – показывает контент;
  • hide – скрывает контент;
  • dispose – уничтожает collapse-элемент (удаляет данные сохраненные в DOM элементе);
  • getInstance (только в Bootstrap v5) – статический метод, который позволяет вам получить экземпляр Collapse, связанный с DOM-элементом;
  • getOrCreateInstance (только в Bootstrap v5) – статический метод, который возвращает экземпляр Collapse, связанный с DOM-элементом, или создает новый, если этот элемент не был инициализирован как Collapse.

Использование методов для управления collapse-элементом:

Методы Bootstrap Collapse
HTML
<!-- Bootstrap 5 -->
<a class="btn btn-primary btn-toggle">toggle</a>
<a class="btn btn-primary btn-show">show</a>
<a class="btn btn-primary btn-hide">hide</a>
<!-- collapse-элемент -->
<div class="collapse" id="target">
  <div class="card card-body">...</div>
</div>

<script>
  const btnToggle = document.querySelector('.btn-toggle');
  const btnShow = document.querySelector('.btn-show');
  const btnHide = document.querySelector('.btn-hide');
  const collapseElement = document.querySelector('#target');
  const collapse = new bootstrap.Collapse(collapseElement, { toggle: false });
  btnToggle.addEventListener('click', (e) => {
    e.preventDefault();
    collapse.toggle();
  });
  btnShow.addEventListener('click', (e) => {
    e.preventDefault();
    collapse.show();
  });
  btnHide.addEventListener('click', (e) => {
    e.preventDefault();
    collapse.hide();
  });
</script>

Этот пример на Bootstrap 4:

HTML
<!-- Bootstrap 4 -->
<a class="btn btn-primary btn-toggle">toggle</a>
<a class="btn btn-primary btn-show">show</a>
<a class="btn btn-primary btn-hide">hide</a>
<!-- collapse-элемент -->
<div class="collapse" id="target">
  <div class="card card-body">...</div>
</div>

<script>
  $('#target').collapse({ toggle: false });
  $('.btn-toggle').click(e => {
    e.preventDefault();
    $('#target').collapse('toggle');
  });
  $('.btn-show').click(e => {
    e.preventDefault();
    $('#target').collapse('show');
  });
  $('.btn-hide').click(e => {
    e.preventDefault();
    $('#target').collapse('hide');
  });
</script>

Методы Bootstrap 5 getInstance и getOrCreateInstance предназначены для получения экземпляра bootstrap.Collapse. Кроме этого, последний метод ещё выполняет создание экземпляра bootstrap.Collapse, если он не создан для указанного элемента.

Пример, в котором будем переключать видимость collapse-элементов каждые 5 секунд. Получать экземпляры bootstrap.Collapse, связанные с указанными элементами, будем с помощью указанных выше методов.

HTML
<!-- Bootstrap 5 -->
<div class="collapse" id="collapse-1">...</div>
<div class="collapse" id="collapse-2">...</div>

<script>
  // создадим bootstrap.Collapse связанный с #collapse-1
  new bootstrap.Collapse(document.querySelector('#collapse-1'), { toggle: false });

  window.setInterval(() => {
    // получим bootstrap.Collapse связанный с #collapse-1
    const collapse1 = bootstrap.Collapse.getInstance('#collapse-1');
    // переключим видимость #collapse-1
    collapse1.toggle();
    // получим bootstrap.Collapse связанный с #collapse-2 (если его нет, то создадим его)
    const collapse2 = bootstrap.Collapse.getOrCreateInstance('#collapse-2');
    // переключим видимость #collapse-2
    collapse2.toggle();
  }, 5000);
</script>

Этот пример на Bootstrap 4:

HTML
<!-- Bootstrap 4 -->
<div class="collapse" id="collapse-1">...</div>
<div class="collapse" id="collapse-2">...</div>

<script>
  // инициализируем #collapse-1 как collapse-элемент
  $('#collpase-1').collapse({ toggle: false });

  window.setInterval(() => {
    // получим collapse-элемент и переключим его видимость
    $('#collapse-1').collapse('toggle');
    // получим collapse-элемент (если он не инициализирован, то инициализируем его как collapse-элемент) и переключим его видимость
    $('#collapse-2').collapse('toggle');
    // переключим видимость #collapse-2
  }, 5000);
</script>

События компонента Collapse

Collapse имеет следующие события:

  • show.bs.collapse – срабатывает сразу после вызова метода show (т.е. перед началом разворачивания);
  • shown.bs.collapse – генерируется, когда collapse-элемент станет полностью видимым для пользователя (т.е. после того как полностью завершится CSS переход);
  • hide.bs.collapse – генерируется сразу после вызова hide (т.е. перед началом сворачивания);
  • hidden.bs.collapse – сработает, когда collapse-элемент будет полностью скрыт от пользователя (т.е. после завершения CSS перехода).

Пример, в котором будем добавлять классы к collapse-элементу (а точнее к .card, расположенным в нём) для изменения цвета фона и текста, после того как он будет полностью виден. А перед началом сворачивания будем удалять их.

Пример обработки событий Bootstrap Collapse
HTML
<!-- Bootstrap 5 -->
<a class="btn btn-primary" href="#" data-bs-toggle="collapse" data-bs-target="#collapse-1">#collapse-1</a>
<div class="collapse mb-3" id="collapse-1">
  <div class="card card-body">...</div>
</div>

<script>
  // получаем элемент #collapse-1
  const collapse = document.querySelector('#collapse-1')
  // после разворачивания (когда содержимое #collapse-1 станет полностью видно)
  collapse.addEventListener('shown.bs.collapse', (e) => {
    const cardEl = e.target.querySelector('.card');
    cardEl.classList.add('bg-primary');
    cardEl.classList.add('text-white');
  });
  // перед началом сворачивания #collapse-1
  collapse.addEventListener('hide.bs.collapse', (e) => {
    const cardEl = e.target.querySelector('.card');
    cardEl.classList.remove('bg-primary');
    cardEl.classList.remove('text-white');
  });
</script>

Этот пример на Bootstrap 4:

HTML
<!-- Bootstrap 4 -->
<a class="btn btn-primary" href="#" data--toggle="collapse" data-target="#collapse-1">#collapse-1</a>
<div class="collapse mb-3" id="collapse-1">
  <div class="card card-body">...</div>
</div>

<script>
  const collapse = $('#collapse-1')
  collapse.on('shown.bs.collapse', (e) => {
    const cardEl = $(e.target).find('.card');
    cardEl.addClass('bg-primary text-white');
  });
  collapse.on('hide.bs.collapse', (e) => {
    const cardEl = $(e.target).find('.card');
    cardEl.removeClass('bg-primary text-white');
  });
</script>

Аккордеон

Компонент Accordion в Bootstrap построен на базе компонента Collapse.

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

Пример аккордеона на Bootstrap 5:

Создание аккордеона в Bootstrap
HTML
<!-- Bootstrap 5 -->
<div class="accordion" id="menu">
  <!-- item-1 -->
  <div class="accordion-item">
    <h2 class="accordion-header">
      <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#item-1">
        Item 1
      </button>
    </h2>
    <!-- класс show делает пункт открытым -->
    <div id="item-1" class="accordion-collapse collapse show" data-bs-parent="#menu">
      <div class="accordion-body">
        Content 1...
      </div>
    </div>
  </div>
  <!-- item-2 -->
  <div class="accordion-item">
    <h2 class="accordion-header">
      <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#item-2">
        Item 2
      </button>
    </h2>
    <div id="item-2" class="accordion-collapse collapse" data-bs-parent="#menu">
      <div class="accordion-body">
        Content 2...
      </div>
    </div>
  </div>
  ...
</div>

В Accordion collapse-элемент, который должен быть открыт по умолчанию, помечается с помощью класса show.

Реализация этого примера на Bootstrap 4:

HTML
<!-- Bootstrap 4 -->
<div class="accordion" id="menu">
  <!-- item-1 -->
  <div class="card">
    <div class="card-header">
      <h2 class="mb-0">
        <button class="btn btn-link btn-block text-left" type="button" data-toggle="collapse" data-target="#item-1">
          Item 1
        </button>
      </h2>
    </div>
    <!-- класс show делает пункт открытым -->
    <div id="item-1" class="collapse show" data-parent="#menu">
      <div class="card-body">
        Content 1...
      </div>
    </div>
  </div>
  <!-- item-2 -->
  <div class="card">
    <div class="card-header">
      <h2 class="mb-0">
        <button class="btn btn-link btn-block text-left" type="button" data-toggle="collapse" data-target="#item-2">
          Item 2
        </button>
      </h2>
    </div>
    <div id="item-2" class="collapse" data-parent="#menu">
      <div class="card-body">
        Content 2...
      </div>
    </div>
  </div>
  ...
</div>

Если мы хотим, чтобы при открытии одного collapse-элемента другие сворачивались, нужно их при помощи атрибута data-bs-parent (в Bootstrap v3 и v4: data-parent) привязать к одному родителю:

HTML
<!-- Bootstrap 5 -->
<!-- элемент, который выступает в качестве родителя (id="menu") -->
<div class="accordion" id="menu">
  ...
  <div id="item-1" class="accordion-collapse collapse show" data-bs-parent="#menu">
  ...
  <div id="item-2" class="accordion-collapse collapse" data-bs-parent="#menu">
  ...
</div>
HTML
<!-- Bootstrap 4 -->
<!-- элемент, который выступает в качестве родителя (id="menu") -->
<div class="accordion" id="menu">
  ...
  <div id="item-1" class="collapse show" data-parent="#menu">
  ...
  <div id="item-2" class="collapse" data-parent="#menu">
  ...
</div>

Если это не нужно, то тогда вышеприведённый пример можно записать так:

HTML
<!-- Bootstrap 5 -->
<div class="accordion">
  <!-- item-1 -->
  <div class="accordion-item">
    <h2 class="accordion-header">
      <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#item-1">
        Item 1
      </button>
    </h2>
    <!-- класс show делает пункт открытым -->
    <div id="item-1" class="accordion-collapse collapse show">
      <div class="accordion-body">
        Content 1...
      </div>
    </div>
  </div>
  <!-- item-2 -->
  <div class="accordion-item">
    <h2 class="accordion-header">
      <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#item-2">
        Item 2
      </button>
    </h2>
    <div id="item-2" class="accordion-collapse collapse">
      <div class="accordion-body">
        Content 2...
      </div>
    </div>
  </div>
  ...
</div>

На Bootstrap 4:

HTML
<!-- Bootstrap 4 -->
<div class="accordion">
  <!-- item-1 -->
  <div class="card">
    <div class="card-header">
      <h2 class="mb-0">
        <button class="btn btn-link btn-block text-left" type="button" data-toggle="collapse" data-target="#item-1">
          Item 1
        </button>
      </h2>
    </div>
    <!-- класс show делает пункт открытым -->
    <div id="item-1" class="collapse show">
      <div class="card-body">
        Content 1...
      </div>
    </div>
  </div>
  <!-- item-2 -->
  <div class="card">
    <div class="card-header">
      <h2 class="mb-0">
        <button class="btn btn-link btn-block text-left" type="button" data-toggle="collapse" data-target="#item-2">
          Item 2
        </button>
      </h2>
    </div>
    <div id="item-2" class="collapse">
      <div class="card-body">
        Content 2...
      </div>
    </div>
  </div>
  ...
</div>

В Bootstrap 5 имеется класс accordion-flush. Если его добавить к accordion то он удалит дефолтный цвет фона, некоторые закругленные углы.

Создание аккордеона в Bootstrap 5 с добавлением к нему класса accordion-flush
HTML
<!-- Bootstrap 5 -->
<div class="accordion accordion-flush" id="menu">
  ...
</div>

Пример кода для динамического создания аккордеона:

HTML
<?php
// сервер
$contents = [
  [
    'title' => '...',
    'content' => '...'
  ],
  ...
];

echo json_encode($contents);
HTML
<!-- клиент -->
<div class="container py-3"></div>

<script>
  const htmlItem = `<div class="accordion-item">
      <h2 class="accordion-header">
        <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#item-{{index}}">
          {{title}}
        </button>
      </h2>
      <div id="item-{{index}}" class="accordion-collapse collapse" data-bs-parent="#menu">
        <div class="accordion-body">
          {{content}}
        </div>
      </div>
    </div>`;
  const accordionEl = document.createElement('div');
  accordionEl.id = 'menu';
  accordionEl.classList.add('accordion');
  let html = '';
  fetch('/examples/json/get-content.php')
    .then((response) => {
      return response.json();
    })
    .then((data) => {
      data.forEach((item, index) => {
        let itemStr = htmlItem.replace('{{title}}', item['title']);
        itemStr = itemStr.replace('{{content}}', item['content']);
        itemStr = itemStr.replaceAll('{{index}}', index + 1);
        html += itemStr;
      });
      accordionEl.innerHTML = html;
      document.querySelector('.container').append(accordionEl);
    });
</script>

Комментарии: 98

pvenats
pvenats

Александр, выручайте! Когда- то Вы мне помогли, теперь еще раз зарегистрировался на Вашем сайте (старый пароль забыл), потому, надеюсь на Вашу помощь. Бьюсь над проблемой аккордиона на движке друпал 8.

Проблема в том, что все работает, но не так как хотелось бы. Дело в том, что при нажатии на панель все открывается как надо, но скрол отбрасывает в начало страницы и приходится опять прокручивать до того места, где расположен блок, чтоб посмотреть результат... Что очень неудобно... Я думаю. что дело именно в движке друпал 8, потому, что на друпал 7 все работает как надо. И через Views bootstrap3, да я и просто с официального сайта: https://getbootstrap.com/docs/3.3/javascript/#collapse-example-accordion

когда делаешь простым блоком.

Вопрос такой: можно ли сделать какой- нибудь костыль прям коде блока, чтобы решить эту проблему? Чтобы оставаться на месте и смотреть сразу то, что открылось, а не прокручивать всякий раз с начала страницы до того места где находится блок?
Александр Мальцев
Александр Мальцев

Добрый день! Так понимаю, вам нужно узнать высоту прокрутки, а затем при повторном открытии страницы установить её на эту величину:

document.addEventListener('DOMContentLoaded', () => {
  const scrolled = localStorage.getItem('scrolled');
  if (scrolled) {
    window.scroll({
      top: scrolled,
      behavior: 'instant'
    });
  }
  window.addEventListener('scroll', () => {
    const scrolled = window.scrollY;
    localStorage.setItem('scrolled', scrolled);
  });
});

Пример на CodePen: codepen.io/itchief/pen/jOeXJVL

Vitaliy
Vitaliy
Доброго времени суток, интересует вопрос о сворачивании блока в спойлер или аккардеон на разрешении sm и ниже.
Пока один вариант меня посетил. Сделать 2 блока и просто один из них скрывать с помощью css на разных разрешениях. Возможно есть иное решение вопроса?
Александр Мальцев
Александр Мальцев
Здравствуйте!
Можно сделать так:
<style>
.spoiler_links {
  display: block;
}
.spoiler_body {
  display: none;
}
@media (min-width: 992px) {
  .spoiler_links {
    display: none;
  }
  .spoiler_body {
    display: block;
  }
}
</style>
...
<a href="#" class="spoiler_links">Спойлер (кликните для открытия/закрытия)</a>
<div class="spoiler_body alert alert-info">
  <p>...</p>
</div>
...
<script>
$(function () {
  $('.spoiler_links').click(function (e) {
    e.preventDefault();
    $(this).next('.spoiler_body').toggle();
  });
});
</script>
Готовый пример доступен по этой ссылке.
Егор
Егор
Здравствуйте. Посмотрел комментарии, не нашел такого. Как реализовать программно, не меняя айдишников вывод нескольких аккордеонов на одной странице?

На WP добавляю блок аккордеон в редактор, так их может быть несколько на странице. С помощью JS? Например $this?
Александр Мальцев
Александр Мальцев
Здравствуйте.
Как вариант можно просто поменять программно id и значение элементов a с href, на которые они ссылаются:
<script>
// получаем все элементы collapse
$('.collapse').each(function(index){
  // получаем текущий id элемент
  var id = $(this).prop('id');
  // установим этому элементу id равный текущему id + индекс
  $(this).prop('id', id + index);
  // найдём элемент в родительском, который ссылается на id и добавим к его href индекс
  $(this).parent().find('[href="#' + id + '"]').attr('href', '#' + id + index);
});
</script>
При этом стандартный механизм Bootstrap останется.

Если нужно как-то по-другому, то тогда нет смысла использовать стандартный механизм Bootstrap, можно вместо него написать своё решение.
Егор
Егор
Спасибо. Это и нужно.
На wordpress делал повторитель в админке, только для одного аккордеона примерно так на PHP: 
$acoord_id = 0; 

Ну а в цикле:
$acoord_id++;
#collapse_<?php echo $acoord_id; ?>
Anush
Anush
Здравствуйте. Помогите, пожалуйста, настроить аккордеон так, чтобы при переходе ну другие страницы, активным стал тот блок, откуда пришли. В комментарии есть пример, но он у меня не работал.
Меню у меня как в «картинке 1»


нужно чтобы при переходе на страницу «КОЗЫРЬКИ И НАВЕСЫ» меню выглядела как в «картинке 2».


Спасибо)
Александр Мальцев
Александр Мальцев
Здравствуйте. Сложно предугадать, что у вас не работает, желательно данное меню привести в «живом» виде (например, на jsfiddle).
Заготовку можно взять по адресу: jsfiddle.net/itchief/ktb3tep4/
Anush
Anush
Доброе утро. У меня не получается (( Помогите, пожалуйста
jsfiddle.net/ktb3tep4/4/
Александр Мальцев
Александр Мальцев
Доброе! Когда вы формируете разметку панелей, для указания переключаемого элемента используйте атрибут data-target, а атрибут href используйте для указания ссылки. Иначе будет невозможно опознать, к какому разделу относится эта ссылка.
...
<!-- Заголовок 1 панели -->
<div class="panel-heading">
  <div class="panel-title">
    <a data-toggle="collapse" data-parent="#accordion" data-target="#collapseOne" href="...">Кованые мангалы <span class="glyphicon glyphicon-chevron-down"></span></a>
  </div>
</div>
...
Скрипт, который необходимо будет добавить ко всем страницам (на которых присутствует аккордеон):
$(function(){
  // определяем путь текущей страницы
  var url = location.pathname.slice(1);
  // если элемент с таким путём есть в аакордионе
  if ($('#accordion a[href*="'+url+'"]').length>0) {
    // то программно для него вызываем событие click
    $('#accordion a[href*="'+url+'"]').closest('.panel').find('.panel-title a').trigger('click');
  }  
});
Виталий
Виталий
Александр, добрый день!
Второй день бьюсь над простейшем казалось бы заданием, необходимо изменять иконку при открытии/закрытии accordion.
Пользовался вашим руководством выше в комментариях, не выходит, в коде два accordion и две иконки, при нажатии на одну, меняются обе.

<div class="col-md-3" id="left_col">
			<div id="filter" class="filter" data-toggle="collapse" data-target="#widgets_div" aria-expanded="true">Фильтр<i class="cursor pull-right pe-2x i-angle-up-z"></i></div>
			<div id="widgets_div" class="widgets_div collapse in" aria-expanded="true"><div class="property"><h4>Строка 1<i id="collapse_s" class="cursor pe-2x pull-right i-angle-down-z collapsed" data-toggle="collapse" data-target="#slider_s" aria-expanded="false"></i></h4><div id="slider_s" class="collapse" data-toggle="false" aria-expanded="false" style="height: 0px;">
$(function() {
	$('#left_col').on('show.bs.collapse', function() {
		$('#filter').find('i').addClass('i-angle-up-z').removeClass('i-angle-down-z');
	});
	$('#left_col').on('hide.bs.collapse', function() {
		$('#filter').find('i').addClass('i-angle-down-z').removeClass('i-angle-up-z');
	});
	$('#left_col').on('show.bs.collapse', function() {
		$('#widgets_div').find('i').addClass('i-angle-up-z').removeClass('i-angle-down-z');
	});
	$('#left_col').on('hide.bs.collapse', function() {
		$('#widgets_div').find('i').addClass('i-angle-down-z').removeClass('i-angle-up-z');
	});
});
Александр Мальцев
Александр Мальцев
В этом случае вам необходимо указать 2 разных селектора, а не один #left_col. Или написать какое-то универсальное решение без привязки к конкретным идентификаторам.
Олег
Олег
Александр здравствуйте!
Пытаюсь решить проблему с меню на одностраничном сайте, дело в том, что хотелось бы, чтобы при нажатии на пункты меню в мобильной версии оно сворачилось — переход по ссылкам в меню с эффектом прокрутки до нужного ID.
Моё меню
<div class="container-fluid">
	<!-- Brand and toggle get grouped for better mobile display -->
	<div class="navbar-header">
		<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
			<span class="sr-only">Toggle navigation</span>
			<span class="icon-bar"></span>
			<span class="icon-bar"></span>
			<span class="icon-bar"></span>
		</button>
	</div>
	<!-- Collect the nav links, forms, and other content for toggling -->
	<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
		<ul class="nav navbar-nav navbar-right">
		<li><a href="/">Главная</a></li>
			<li><a href="#" class="animated delay3 about-more">1</a></li>
			<li><a href="#" class="animated delay3 about-more">2</a></li>
			<li><a href="#" class="animated delay3 about-more">3</a></li>
			<li><a href="#" class="animated delay3 about-more">4</a></li>
		</ul>
	</div><!-- /.navbar-collapse -->
</div>
Уже много всего перелопатил но никак не могу получить результат. Пытался играть с dropdown-menu, но вкупе с классами анимации прокрутки все перестает работать. Я уже обрадовался, кода нашел у вас способ с помощью скрипта

<script type="text/javascript">
$(document).ready(function(){
    $("a").click(function(){
        $("#toggleSample2").collapse('toggle');
    });
});
</script>
Но при таком варианте сворачивание и разворачивание происходит при нажатии на любой ссылке на сайте, а нужно, только при нажатии в выпадающем меню в мобилной версии.
Подскажите в этой проблеме, если можете.
Александр Мальцев
Александр Мальцев
Добавьте не для всех ссылок, а только для тех, которые расположены в меню. Но и проверить ширину экрана необходимо:
$(document).ready(function(){
    $(".navbar-collapse a").click(function() {
        if (window.matchMedia('screen and (max-width: 767px)').matches) {
          $("#toggleSample2").collapse('toggle');
        }
    });
});
Олег
Олег
Александр спасибо за помощь, теперь работает ка надо. Очень благодарен!!!
Tracktor
Tracktor
Все комменты не изучил, извините, если повторяюсь, направьте пожалуйста, к нужному.
Вопрос такой — можно ли сделать, чтобы положения аккордеона запоминались? Например, у меня на странице закрытый блок

<!-- HTML код управляемого элемента -->
<input type="button" class="btn btn-primary" data-toggle="collapse" data-target="#toggleSample" value="Элемент управления">
<!-- HTML код сворачиваемого элемента -->
<div id="toggleSample" class="collapse">
  <p style="background: #F9F9F9; border: 1px solid #E1E1E8; margin: 10px 0; padding: 8px;">
На этом примере показана возможность сворачивания и разворачивания элемента с помощью data атрибутов. Нажмите на <b>кнопку</b>, чтобы увидеть этот эффект.
  </p>
</div>
Пользователь зашёл на страницу, раскрыл его. Но когда обновил старицу — он остался раскрытым? И наоборот, если есть раскрытый, пользователь его закрыл, обновил страницу (или полазил по другим и вернулся на эту), а аккордеон остался в том же положении, в котором его оставил пользователь. Предполагаю, что это как-то можно сделать с помощью php или js с использованием куки, но как именно — не знаю…
Александр Мальцев
Александр Мальцев
В данном случае лучше использовать не COOKIE, а LocalStorage.
$(function(){
  idCollapse = 'toggleSample';
  // при открытии добавляем в хранилище ключ toggleSample
  $('#'+idCollapse).on('shown.bs.collapse', function () {
    localStorage.setItem(idCollapse, 'in');
    console.log('dd');
  });
  // при скрытии удаляем из хранилища ключ toggleSample
  $('#'+idCollapse).on('hidden.bs.collapse', function () {
    localStorage.removeItem(idCollapse);
  });
  // проверяем если ли значение в LocalStorage, и в зависимости от него открываем или скрываем содержимое
  if (localStorage.getItem(idCollapse) != null) {
    $('#'+idCollapse).addClass('in');
  } else {
    $('#'+idCollapse).removeClass('in');  
  }
});
Tracktor
Tracktor
Отлично работает, спасибо! Про LocalStorage даже не знал.
Дмитрий
Дмитрий
У меня в коде используется несколько id: collapse1, collapse2, collapse3. Хотел сделать, чтобы посетитель при возвращении на страницу с аккордеоном видел открытой ту панель, которую ранее открыл. Я скопировал этот код три раза и подставил свои id, но у меня получилось, что открывается только нижняя панель. Подскажите пожалуйста возможно ли поправить код, чтобы по возвращение на страницу открывалась та панель, которая была открыта.

$(function() {

idCollapse = 'collapse1';
$('#'+idCollapse).on('shown.bs.collapse', function () {
localStorage.setItem(idCollapse, 'in');
console.log('dd');
});
$('#'+idCollapse).on('hidden.bs.collapse', function () {
localStorage.removeItem(idCollapse);
});
if (localStorage.getItem(idCollapse) != null) {
$('#'+idCollapse).addClass('in');
} else {
$('#'+idCollapse).removeClass('in');
}

idCollapse = 'collapse2';
$('#'+idCollapse).on('shown.bs.collapse', function () {
localStorage.setItem(idCollapse, 'in');
console.log('dd');
});
$('#'+idCollapse).on('hidden.bs.collapse', function () {
localStorage.removeItem(idCollapse);
});
if (localStorage.getItem(idCollapse) != null) {
$('#'+idCollapse).addClass('in');
} else {
$('#'+idCollapse).removeClass('in');
}

idCollapse = 'collapse3';
$('#'+idCollapse).on('shown.bs.collapse', function () {
localStorage.setItem(idCollapse, 'in');
console.log('dd');
});
$('#'+idCollapse).on('hidden.bs.collapse', function () {
localStorage.removeItem(idCollapse);
});
if (localStorage.getItem(idCollapse) != null) {
$('#'+idCollapse).addClass('in');
} else {
$('#'+idCollapse).removeClass('in');
}
});
Вячеслав
Вячеслав
Здравствуйте. Может поможете и мне.
У меня акардеон типа:
<ul id="accordion1">
    <li>
       <a href="#parent_1" data-toggle="collapse" data-parent="#accordion1">Категория1</a>
    </li>    
    <ul class="collapse" id="parent_1">
        <li><a href="#">Подкатегория1</a></li>    
        <li><a href="#">Подкатегория2</a></li>    
    </ul>
    <li>
      <a href="#parent_2" data-toggle="collapse" data-parent="#accordion1">Категория2</a>
    </li>    
    <ul class="collapse" id="parent_2">
        <li>
            <a href="#">Подкатегория3</a>
        </li>    
    </ul>
</ul>
Куда тут можно вставить data-parent, чтобы при открытии второго элемента первый закрылся?
Александр Мальцев
Александр Мальцев
В данном примере это сделать не получится, т.к. его работа связана с классом panel.
В этом случае можно использовать следующий скрипт:
$(function(){
  $('#accordion1 .collapse').on('show.bs.collapse', function () {
    $('#accordion1 .collapse').not(this).removeClass('in');
  });
});
Larisa
Larisa
здравствуйте! у меня аналогичная проблема — надо сделать аккордеон без класса panel, применяю ваш js — не работает :(
<section class="catalog-wrap solutions" id="accordion1">
    <div class="container">
<div class="category-single">
        <div class="category-title">
          <a class="category-name collapsed" href="#category2" data-toggle="collapse" data-parent="#accordion1"  aria-expanded="false" aria-controls="category2"><span class="caret-control"></span>Кабинеты</a>
        </div><!-- //.category-title -->
        <div class="separator"></div>
        <div class="sub-category sub-first-level collapse" id="category2">
          <div class="sub-category-single">
            <div class="category-title">
              <a class="category-name" href="#">Общие данные</a>
              <div class="category-action pull-right">
                <a href="#">Редактировать</a>
                <a href="#">Удалить</a>
              </div>
            </div><!-- //.category-title -->
            <div class="separator"></div>

            <div class="category-title">
              <a class="category-name " href="#">Система микрофонов</a>
              <div class="category-action pull-right">
                <a href="#">Редактировать</a>
                <a href="#">Удалить</a>
              </div>
            </div><!-- //.category-title -->
            <div class="separator"></div>

            <div class="category-title">
              <a class="category-name" href="#">Система отображения видео</a>
              <div class="category-action pull-right">
                <a href="#">Редактировать</a>
                <a href="#">Удалить</a>
              </div>
            </div><!-- //.category-title -->
            <div class="separator"></div>

            <div class="category-title" id="subcategoryTitle1">
              <a class="category-name" href="#">Система обработки видео</a>
              <div class="category-action pull-right" id="subAction1">
                <a href="#">Редактировать</a>
                <a href="#">Удалить</a>
              </div>
            </div><!-- //.category-title -->
            <div class="separator" id="subseparator1"></div>
          </div>
        </div><!-- //.sub-first-level -->
      </div><!-- //.category-single -->
<div class="category-single">
        <div class="category-title" id="categoryTitle1">
          <a class="category-name collapsed" href="#category1" data-toggle="collapse" data-parent="#accordion1" aria-expanded="false" aria-controls="category1"><span class="caret-control"></span>Переговорные</a>
        </div><!-- //.category-title -->
        <div class="separator" id="separator1"></div>
        <div class="sub-category sub-first-level collapse" id="category1">
          <div class="sub-category-single">
            <div class="category-title">
              <a class="category-name" href="#">Общие данные</a>
              <div class="category-action pull-right">
                <a href="#">Редактировать</a>
                <a href="#">Удалить</a>
              </div>
            </div><!-- //.category-title -->
            <div class="separator"></div>

            <div class="category-title">
              <a class="category-name " href="#">Система микрофонов</a>
              <div class="category-action pull-right">
                <a href="#">Редактировать</a>
                <a href="#">Удалить</a>
              </div>
            </div><!-- //.category-title -->
            <div class="separator"></div>

            <div class="category-title">
              <a class="category-name" href="#">Система отображения видео</a>
              <div class="category-action pull-right">
                <a href="#">Редактировать</a>
                <a href="#">Удалить</a>
              </div>
            </div><!-- //.category-title -->
            <div class="separator"></div>

            <div class="category-title" id="subcategoryTitle1">
              <a class="category-name" href="#">Система обработки видео</a>
              <div class="category-action pull-right" id="subAction1">
                <a href="#">Редактировать</a>
                <a href="#">Удалить</a>
              </div>
            </div><!-- //.category-title -->
            <div class="separator" id="subseparator1"></div>
          </div>
        </div><!-- //.sub-first-level -->
      </div><!-- //.category-single -->
</div><!-- //.container -->
</section>
Александр Мальцев
Александр Мальцев
Нет должно всё работать: jsfiddle.net/itchief/3te1g8vt/
Если не так, то обновите версию Bootstrap 3 на последнюю 3.3.7.
Если это не возможно, то попробуйте так:
$(function(){
  $('#accordion1 .collapse').on('show.bs.collapse', function () {
    $('#accordion1 .sub-first-level').not(this).removeClass('in');
  });
});
Dmitry
Dmitry
Добрый вечер, Александр.
Возник вопрос касательно аккордеона и высоты блоков после его сворачивания, как сделать так, чтобы высота страницы возвращалась на начальную позицию. Проблема на скрине. Заранее спасибо.
Александр Мальцев
Александр Мальцев
Здравствуйте. Проверьте стили, т.к. высота по умолчанию и так должна возвращаться в первоначальное состояние.
Алексей
Алексей
Добрый день!
Пытаюсь сохранить состояние открытой панели аккордиона через cookie. Но никак не могу добиться чтобы нужная панель разворачивалась при перезагрузке страницы:
<script type="text/javascript">
			//$("#accordion").accordion();					// Оформление страницы типа "аккордион"
			$(function()	{ $("#accordion").accordion(
						{ autoHeigth: false,
						  //active: GetCookie("accordion"),
						  activate: function(click){save();}
						});
					});
			var tab_index = $("#tabs").tabs("option", "selected") + 1;	// Переменная  для tabs

			// Отображение данных при загрузке страницы
			$(document).ready(function()
			{	push();
			});


			function save()
			{ var active = $("#accordion").accordion( "option", "active" );
			  SetCookie("accordion", active);
			  alert("Save = " +active);
			}
			
			function push()
			{ var active = GetCookie("accordion");
			  if(active == '') active = 0;
			  alert("accordion = " +active);
			  $("#accordion").accordion( "option", "active", active);
			}
			
		</script>
Если в push(); переменной active присваиваю 2, то при активации функции все работает, а если var active = GetCookie(«accordion»); то не работает! В чем проблема-то?

UPD: написав пост, сам себе ответил! При var active = parseInt( GetCookie(«accordion») ); все заработало.
А как можно сделать все лаконичнее???
Александр Мальцев
Александр Мальцев
Здравствуйте. Вы используете не Bootstrap аккордеон, а jQuery UI.
Оптимизировать код можно как-то так:
$(function(){
  var accrd = $("#accordion");
  accrd.accordion({
    autoHeigth: false,
    activate: function(click){save();}
  });
  function save(){
    var active = accrd.accordion("option","active");
    SetCookie("accordion", active);
  }
  function push(){ 
    var active = parseInt(GetCookie("accordion")) || 0;
    accrd.accordion("option","active",active);
  }  
  push();
});
controllix
controllix
Здравствуйте! Подскажите, пожалуйста, как сделать, чтобы содержимое в раскрывающемся блоке было подгружаемым? Т.е. контента не было заранее на странице до нажатия на кнопку раскрытия.
Александр Мальцев
Александр Мальцев
Добрый день. Для этого можно воспользоваться функцией jQuery load.
Например, можно реализовать так.
1. Создать необходимые файлы с содержимым на сервере. Например, content1.txt, content2.txt и content3.txt.
2. На необходимую страницу (например, accordeon.html) вставить HTML-код аккордеона
<div class="panel-group" id="accordion">
  <div class="panel panel-default">
    <div class="panel-heading">
      <h4 class="panel-title">
        <a data-toggle="collapse" data-parent="#accordion" href="#content1">Контент 1</a>
      </h4>
    </div>
    <div id="content1" class="panel-collapse collapse">
      <div class="panel-body">
      </div>
    </div>
  </div>
  <div class="panel panel-default">
    <div class="panel-heading">
      <h4 class="panel-title">
        <a data-toggle="collapse" data-parent="#accordion" href="#content2">Контент 2</a>
      </h4>
    </div>
    <div id="content2" class="panel-collapse collapse">
      <div class="panel-body">
      </div>
    </div>
  </div>
  <div class="panel panel-default">
    <div class="panel-heading">
      <h4 class="panel-title">
        <a data-toggle="collapse" data-parent="#accordion" href="#content3">Контент 3</a>
      </h4>
    </div>
    <div id="content3" class="panel-collapse collapse">
      <div class="panel-body">
      </div>
    </div>
  </div>
</div>
3. В эту же страницу (accordeon.html) добавить сценарий JavaScript, который и будеть выполнять всю эту «магию»:
<script>
$(function(){
  $('#accordion .collapse').on('show.bs.collapse', function () {
    $(this).find('.panel-body').load(this.id+'.txt');
  });
});
</script>
Файл accordeon.html и файлы с содержимым (content1.txt, content2.txt и content3.txt) должны находиться в одном каталоге.
Проверять работоспособность примера необходимо на сервере.
chendlermon
chendlermon
Здравствуйте. Скажите пожалуйста, почему у меня не открывается содержимое панелей? я вставил даже код из вашего примера, но результат тот же.
п.с. в адресной строке браузера видно как происходит переход (#collapse1,#collapse2,#collapse3), но панели не раскрываются.
Александр Мальцев
Александр Мальцев
Добрый день. Скорее всего, вы не подключили плагин Bootstrap (bootstrap.js), либо его подключили до подключения библиотеки jQuery. Или расположили свой код до подключения плагина Bootstrap. Проверьте эти моменты.
chendlermon
chendlermon
Да, он был до jquery. спасибо большое!
На локальном теперь все работает, но на вордпрессе, вообще панелей нет (только открытый текст — заголовок, содержимое). Установил плагин Bootstrap 3 Shortcodes, потом Accordion Shortcodes — ситуация не меняется.
Александр Мальцев
Александр Мальцев
На WordPress попробуйте подключить Bootstrap посредством написания своей функции с использованием wp_enqueue_script() и wp_enqueue_style().
Вячеслав
Вячеслав
Добрый день! Подскажите, как сделать чтобы менялся текст кнопки при сворачивании и разворачивании. Например: «Показать содержимое» -> после того как развернулся блок, текст поменялся на «Скрыть содержимое». Заранее спасибо!
Александр Мальцев
Александр Мальцев
Здравствуйте. Необходимо использовать события show.bs.collapse и hide.bs.collapse:
<button id="controlContent" class="btn btn-danger" data-toggle="collapse" data-target="#toggleContent">Показать содержимое</button>

<div id="toggleContent" class="collapse">
  Контент...
</div>

<script>
$(function(){
  $('#toggleContent').on('show.bs.collapse', function(){
    $('#controlContent').text('Скрыть содержимое');
  });
  $('#toggleContent').on('hide.bs.collapse', function(){
    $('#controlContent').text('Показать содержимое');
  });
});
</script>
Вячеслав
Вячеслав
Спасибо большое!
Леонид
Леонид
Здравствуйте Александр!
Спасибо большое за вашу помощь! Возникла еще одна проблема. Мобильное меню использует тот же плагин collapse. Как можно реализовать в мобильном меню добавление/удаление класса для (fa-chevron) как в предыдущем примере. И раскрытие вложенных меню более плавными. Помогите пожалуйста!
Александр Мальцев
Александр Мальцев
Здравствуйте.
Добавление значка к dropdown navbar (аналогично вышеприведённому коду):
<nav class="navbar navbar-default">
<!-- ... -->
  <div class="collapse navbar-collapse" id="main-menu">
    <ul class="nav navbar-nav">
      <!-- ... -->
      <li class="dropdown">
        <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown 
          <span class="chevron">
     	    <i class="fa fa-chevron-down" aria-hidden="true"></i>
          </span>
          <ul class="dropdown-menu">
            <!-- ... -->
Управление отображением иконок вложенных меню (добавление и удаление классов):
$(function() {
  $('#main-menu .dropdown').on('show.bs.dropdown', function() {
    $(this).find('.chevron i').removeClass('fa-chevron-down').addClass('fa-chevron-up');
  });
  $('#bs-example-navbar-collapse-1 .dropdown').on('hide.bs.dropdown', function() {
    $(this).find('.chevron i').removeClass('fa-chevron-up').addClass('fa-chevron-down');
  });
});
Леонид
Леонид
Здравствуйте Александр!
Подскажите пожалуйста, как сделать правильно следующее…
<div class="panel-group" id="accordion">
  <!-- 1 панель -->
  <div class="panel panel-default">
    <!-- Заголовок 1 панели -->
    <div class="panel-heading data-toggle="collapse" data-parent="#accordion"">
      <h4 class="panel-title">
		Заголовок
      </h4>
     <span class="chevron">
     	<i class="fa fa-chevron-down" aria-hidden="true"></i>
    </span>
    </div>
    <div id="collapseOne" class="panel-collapse collapse in">
      <!-- Содержимое 1 панели -->
      <div class="panel-body">
        <p>
		...
	</p>
      </div>
    </div>
  </div>
</div>
В этой конструкции надо чтоб при раскрытом блоке span class=«chevron» добавлялся класс chevron-up, пробовал на js сделать так
...
        $('#accordion .collapse').on('show.bs.collapse', function () {
            if ($('#accordion').hasClass('panel-active')) {
                $('.panel-heading').find('.chevron').addClass('toggle');
            }
        })
...
Вроде работает но не правильно! Надо чтоб при развернутом блоке добавлялся класс, а при сворачивании удалялся. Не могу решить…
Александр Мальцев
Александр Мальцев
Можно реализовать так:
$(function() {
  $('#accordion .collapse').on('show.bs.collapse', function() {
    $(this).prev('.panel-heading').find('.chevron').addClass('chevron-up');
  });
  $('#accordion .collapse').on('hide.bs.collapse', function() {
    $(this).prev('.panel-heading').find('.chevron').removeClass('chevron-up');
  });
});
Если же вы хотите изменять иконку, то следует выполнить следующим образом:
$(function() {
  $('#accordion .collapse').on('show.bs.collapse', function() {
    $(this).prev('.panel-heading').find('.chevron i').removeClass('fa-chevron-down').addClass('fa-chevron-up');
  });
  $('#accordion .collapse').on('hide.bs.collapse', function() {
    $(this).prev('.panel-heading').find('.chevron i').removeClass('fa-chevron-up').addClass('fa-chevron-down');
  });
});
Леонид
Леонид
Спасибо Александр! Но не работает(
Александр Мальцев
Александр Мальцев
У вас ошибки в HTML коде, необходимо их исправить (должно быть так):
  <div class="panel-heading" data-toggle="collapse" data-parent="#accordion">
После этого должно заработать.
Леонид
Леонид
Изиняюсь Александр! Все работает чудесно! Дело в том, что кэш не сбросил…
Эту ошибку заметил еще когда первый пост делал.
<div class="panel-heading data-toggle="collapse" data-parent="#accordion"">
Спасибо вам огромное!
Лорик
Лорик
Добрый день, Александр!

"… Следующий пример демонстрирует методы Bootstrap для сворачиваемых элементов. Нажмите на кнопки чтобы увидеть работу этих методов."

над этим текстом есть кнопки, но нажатие на них не демонстрирует заявленного показа.
Я что-то не то делаю или что-то поломалось?
Александр Мальцев
Александр Мальцев
Здравствуйте, поправил.
Алексей
Алексей
Здравствуйте Александр.
Извините, за возможно глупый вопрос. Не пойму, за счет чего реализована анимация раскрытия 'collapse блока'. Скрипт добавляет height:auto (в закрытом состоянии height:0px), но это свойство (как я понимаю) при помощи css не анимируется. Где магия?
И еще один вопрос. Как сделать чтобы 'collapse- блок' закрывался по клику вне блока, по аналогии с dropdown-menu?
Спасибо, вы уже очень много раз мне помогли…
Александр Мальцев
Александр Мальцев
Здравствуйте, Алексей. Анимация открытия и закрытия блока collapse осуществляется в Bootstrap с помощью CSS свойства transition.
Для скрытия блока collapse (при клике вне его) необходимо добавить следующий сценарий JavaScript на страницу:
// collapse - id collapse-блока 
$(document).click(function(event) {
  if ($(event.target).parents('#collapse').length==0) {
    $('#collapse').collapse('hide');
  };
});
Аноним
Аноним
Добрый день!
А можно ли так сделать чтобы при открытии аккордеон не сдвигал все вниз а открывался поверх контента который идет ниже по структуре?
Александр Мальцев
Александр Мальцев
Используйте для этого компонент popover.
Аноним
Аноним
Но это немного не то. Аккордеон я использую как расширение приложения, то есть при определенных условиях форма приложения расширяется и в данном блоке появляется дополнительный функционал (кнопки и т.п.) Поповер я же не смогу настроить так чтобы он стал цельным продолжением основного div (и по форме и по оформлению)?!
Александр Мальцев
Александр Мальцев
Понятно. Тогда необходимо использовать абсолютное позициониование.
Т.е. помещаем карусель в блок div и задаём ему относительное позиционирование и необходимую высоту. А карусели — абсолютное позиционирование.
<div style="position: relative; height: 150px;">
  <div class="panel-group" id="accordion" style="position: absolute; top: 0; right: 0; left: 0;">
    <!-- содержимое карусели -->
  </div>
</div>
Alex
Alex
Александр, подскажите а возможно ли сделать такие блоки таким образом, что-бы кроме текста еще было и изображение?
Александр Мальцев
Александр Мальцев
А что Вам мешает, используйте. Для этого необходимо добавить элемент с тегом img.
Аноним
Аноним
Подскажите пожалуйста, как сделать ссылку на содержимое вкладки аккордеона?
Аккордеон и пункты меню будут на одной странице.
Нужно сделать так, чтобы когда кликали на «Вкладка 1» Открывался пункт меню «Вкладка 1» с содержимым текстом, и так же для «Вкладка 2» и т.д

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">

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

<!-- Меню на первой странице index.html -->
<nav class="navbar navbar-default">
  <ul class="nav navbar-nav navbar-right">
    <li><a href="#collapse-1">Вкладка 1</a>
    </li>
    <li><a href="#collapse-2">Вкладка 2</a>
    </li>
    <li><a href="#collapse-3">Вкладка 3</a>
    </li>
  </ul>
</nav>

<!-- Аккордион на второй странице index2.html -->
<div id="accordion" class="panel-group">
  <div class="panel panel-default">
    <div class="panel-heading">
      <h2 class="panel-title"><a href="#collapse-1" data-parent="#accordion" data-toggle="collapse">Вкладка 1</a></h2>
    </div>
    <div id="collapse-1" class="panel-collapse collapse in">
      <div class="panel-body">
        <p>Текст 1</p>
      </div>
    </div>
  </div>
  <div class="panel panel-default">
    <div class="panel-heading">
      <h2 class="panel-title"><a href="#collapse-2" data-parent="#accordion" data-toggle="collapse">Вкладка 2</a></h2>
    </div>
    <div id="collapse-2" class="panel-collapse collapse">
      <div class="panel-body">
        <p>Текст 2</p>
      </div>
    </div>
  </div>
  <div class="panel panel-default">
    <div class="panel-heading">
      <h2 class="panel-title"><a href="#collapse-3" data-parent="#accordion" data-toggle="collapse">Вкладка 3</a></h2>
    </div>
    <div id="collapse-3" class="panel-collapse collapse">
      <div class="panel-body">
        <p>Текст 3</p>
      </div>
    </div>
  </div>
</div>
Александр Мальцев
Александр Мальцев
Добавьте к ссылкам data-атрибуты:
<nav class="navbar navbar-default">
  <ul class="nav navbar-nav navbar-right">
    <li><a href="#collapse-1" data-parent="#accordion" data-toggle="collapse">Вкладка 1</a></li>
    <li><a href="#collapse-2" data-parent="#accordion" data-toggle="collapse">Вкладка 2</a></li>
    <li><a href="#collapse-3" data-parent="#accordion" data-toggle="collapse">Вкладка 3</a></li>
  </ul>
</nav>
Аноним
Аноним
Добрый день, Александр, подскажите, пожалуйста, есть ли способ реализации ниже приведенной задачи:

Задача: имеется список элементов(платежи в системе, количество их не известно), он обновляется/добавляется автоматически по оплате. При нажатии на элемент, должен выпадать «аккордеон» с подробной информацией о платеже.

Проблема: при нажатии на любой существующий платеж, открывается первый и только первый элемент из всего списка…
если, я правильно понимаю, то, у каждого элемента для открытия должен быть уникальный id… такой синтаксис не правильный

<tr th:each="pay: ${pays}">
                <td colspan="7">
                    <table>
                        <tr>
                            <td><a href="#" data-toggle="collapse" data-target="#${pay.id}" class="clickable glyphicon glyphicon-chevron-right"></a>
или это решается совсем другим образом?
Александр Мальцев
Александр Мальцев
Добрый. Вам необходимо написать цикл, который будет переберать все платежи в системе и информацию о них. Идентификатор, который у Вас содержится в data-target должен соответствовать id блоку, который необходимо отображать при нажатию на эту ссылку. Т.е. каждая ссылка должна содержать уникальный идентификатор того элемента, который она должна открыть.
Аноним
Аноним
Да, спасибо, не правильно указывал именно id
Аноним
Аноним
Александр, здравствуйте! Отложил я в свое время погружение в JS, о чем теперь люто сожалею, и прошу вашей помощи) Подскажите, как сделать сворачивание одного collapse при открытии другого в такой верстке:

ba.streetsites.ru/test2.html
Код:
<!-- Bootstrap Core CSS -->
    <link href="/assets/ba/css/bootstrap.min.css" rel="stylesheet">
    <!-- jQuery--> 
    <script src="/assets/ba/js/jquery.js"></script>
    <!-- Bootstrap Core JavaScript -->
    <script src="/assets/ba/js/bootstrap.min.js"></script>
    
    
<div class="container">
<div class="row">

<div class="panel-group" id="accordion">
 
 
  <!-- 1 панель -->
  <div class="col-md-4">
  <div class="panel panel-default">
    <!-- Заголовок 1 панели -->
    <div class="panel-heading">
      <h4 class="panel-title">
        <a data-toggle="collapse" data-parent="#accordion" href="#collapseOne">1. col-md-4</a>
      </h4>
    </div>
    </div>
    </div>
    
 
  <!-- 2 панель -->
  <div class="col-md-4">
  <div class="panel panel-default">
    <!-- Заголовок 2 панели -->
    <div class="panel-heading">
      <h4 class="panel-title">
        <a data-toggle="collapse" data-parent="#accordion" href="#collapseTwo">2. col-md-4</a>
      </h4>
    </div>
    </div>
    </div>
  
  
  <!-- 3 панель -->
  <div class="col-md-4">
  <div class="panel panel-default">
    <!-- Заголовок 3 панели -->
    <div class="panel-heading">
      <h4 class="panel-title">
        <a data-toggle="collapse" data-parent="#accordion" href="#collapseThree">3. col-md-4</a>
      </h4>
    </div>
    </div>
    </div>


        <hr>
       
    <div class="col-md-12">    
    <div id="collapseOne" class="panel-collapse collapse">
     <div class="panel-body">
        <p>div class="col-md-12"</p>
        <img alt="" class="img-responsive img-portfolio img-hover" src="http://placehold.it/700x450" /> </a>
      </div>
    </div>
    </div>
    
    
    <div class="col-md-12"> 
    <div id="collapseTwo" class="panel-collapse collapse">
      <div class="panel-body">
        <p>div class="col-md-12"</p>
        <img alt="" class="img-responsive img-portfolio img-hover" src="http://placehold.it/700x450" /> </a>
      </div>
    </div>
     </div>
    
    <div class="col-md-12">
    <div id="collapseThree" class="panel-collapse collapse">
      <div class="panel-body">
        <p>div class="col-md-12"</p>
        <img alt="" class="img-responsive img-portfolio img-hover" src="http://placehold.it/700x450" /> </a>
      </div>
    </div>
    </div> 
     </div>
     </div>
     
     
     <div class="row">
<div class="col-lg-12">
<h2 class="page-header">header</h2>
</div>

<div class="col-md-3 col-sm-6"><a href="portfolio-item.html"><img alt="" class="img-responsive img-portfolio img-hover" src="http://placehold.it/700x450" /> </a></div>

<div class="col-md-3 col-sm-6"><a href="portfolio-item.html"><img alt="" class="img-responsive img-portfolio img-hover" src="http://placehold.it/700x450" /> </a></div>

<div class="col-md-3 col-sm-6"><a href="portfolio-item.html"><img alt="" class="img-responsive img-portfolio img-hover" src="http://placehold.it/700x450" /> </a></div>

<div class="col-md-3 col-sm-6"><a href="portfolio-item.html"><img alt="" class="img-responsive img-portfolio img-hover" src="http://placehold.it/700x450" /> </a></div>

<div class="col-md-3 col-sm-6"><a href="portfolio-item.html"><img alt="" class="img-responsive img-portfolio img-hover" src="http://placehold.it/700x450" /> </a></div>

<div class="col-md-3 col-sm-6"><a href="portfolio-item.html"><img alt="" class="img-responsive img-portfolio img-hover" src="http://placehold.it/700x450" /> </a></div>

<div class="col-md-3 col-sm-6"><a href="portfolio-item.html"><img alt="" class="img-responsive img-portfolio img-hover" src="http://placehold.it/700x450" /> </a></div>

<div class="col-md-3 col-sm-6"><a href="portfolio-item.html"><img alt="" class="img-responsive img-portfolio img-hover" src="http://placehold.it/700x450" /> </a></div>
</div>
<!-- /.row --><!-- Features Section -->

</div>
     
     <script>
$(function() {
  $('.btn').on('click', function(e) {
    e.preventDefault();
    $('.panel-collapse').each(function() { // закрыть все панели
      $(this).css('display', 'none');
    });
    var block = $(this).attr('href'); // найти блок по id в ссылке
    if($(block).css('display')=='block'){
        $(block).css('display', 'none');
      }
      else{
        $(block).css('display', 'block');
      }
    
  
  });
});
</script>

Александр Мальцев
Александр Мальцев
Данную задачу можно решить через замыкания JavaScript. Замыкание нам необходимо чтобы сохранить информацию о предыдущем состоянии панели.
Решение будет следующим:
<script>
$(function() {

  var accordion = function(){
    var currentPanel = $('#accordion .panel-collapse.in');
    console.log('currentPanel='+currentPanel);
    var idCurrentPanel = currentPanel.attr('id');
    console.log('idCurrentPanel='+idCurrentPanel);
    var currentHref;
    if (idCurrentPanel) {
      currentHref = '#'+idCurrentPanel;
    }
    console.log('currentHref='+currentHref);
    return function(myHref) {
      console.log('href='+myHref);
      var newPanel = $('#accordion ' + myHref);
      console.log(newPanel);
      var idNewPanel = newPanel.attr('id');
      console.log('idNewPanel='+idNewPanel);
      console.log('idCurrentPanel='+idCurrentPanel);
      if(idCurrentPanel!=idNewPanel) {
        if (currentPanel) {
          currentPanel.removeClass('in');
        }
        newPanel.addClass('in');
        currentHref = myHref;
        currentPanel = newPanel;
        idCurrentPanel = idNewPanel;
      }
      else {
        currentPanel.toggleClass('in');
      }
    };
  };
  
  var accrdn = accordion();

  $('#accordion a[data-toggle="collapse"]').click(function(e) {
    e.preventDefault();
    e.stopPropagation();
    accrdn($(this).attr('href'));
  });

});
</script>
Аноним
Аноним
Александр, спасибо огромное! Буду разбирать ваш код для понимания процесса. У вас отличный ресурс — есть что почитать, и советом вот помогли) Спасибо еще раз!
Аноним
Аноним
Доброго времени суток!
Есть 5 ссылок на странице1. Есть аккордеон на странице2. Как сделать чтобы при переходе на страницу2 с аккордеоном открывался блок с той ссылкой по которой мы кликнули на странице1? Типа ссылка3 открывает содержимое блока3.
Александр Мальцев
Александр Мальцев
Добавить на 1 странице к ссылкам хэш:
<a href="index2.html#collapseOne">Страница 2 (вкладка 1)</a>
<a href="index2.html#collapseTwo">Страница 2 (вкладка 2)</a>
<a href="index2.html#collapseThree">Страница 2 (вкладка 3)</a>
<!-- collapseOne, collapseTwo, collapseThree - id блоков аккордеона -->
На второй странице (index2.html) добавить скрипт. Он будет считывать хэш и активировать ту или иную вкладку. Если хэш не найден, то будет активировать 1 блок.
<script>
$(function(){
  var hash = window.location.hash;
  $('.panel-collapse').hide();
  $('.panel-collapse').each(function(){
    $(this).removeClass('in');
  });
  if (hash) {
    $(hash).show().addClass('in');
  }
  else {
    $('#collapseOne').show().addClass('in');
  }
});
</script>
Аноним
Аноним
Большое спасибо, Александр!
Аноним
Аноним
Здравствуйте, Александр!
При переходе по ссылке с хэш открывается нужная вкладка.
Но далее если на странице есть меню с другими вкладками, то они не работают.
Скрипт читает url в котором #collapseOne и всегда показывает этот слой.
Видимо надо сделать как то по другому.
Если хэша нет, то как бы и скрипта нет. Т.к. нужный открытый слой можно выбрать и самому параметром in.
Если есть хэш, то открыть нужный слой и как бы убрать скрипт из работы.
Что бы он срабатывал 1 раз при загрузке страницы и больше не мешал отрабатывать бутстрапу.
Александр Мальцев
Александр Мальцев
Здравствуйте. Попробуйте следующий скрипт:
$(function(){
  var hash = window.location.hash;
  // accordion - id аккордеона, в котором необходимо управлять панелями с помощью хэша
  $("#accordion .panel-collapse").removeClass('in');
  if (hash) {
    $("#accordion "+hash).addClass("in");
  }  
});
Аноним
Аноним
Александр, большое спасибо, что откликнулись. У вас отличный сайт и вы отлично его развиваете.
В общем я подошел по другому к решению этого вопроса. Я решил не вмешиваться в работу collapse.js, тем паче таким грубым способом, меняя в обход класс in.
Я с эмулировал работу плагина через событие клика.
var hash = window.location.hash;
jQuery(document).ready( function() { jQuery('hash').trigger("click"); } );
Остается только добавить в ссылку id. Если hash = #el1, то id = el1
<a href="index2.html#collapseOne" id="el1">Страница 2 (вкладка 1)</a>
Еще раз спасибо!!!
Аноним
Аноним
Доброго времени суток, Александр.

Можно ли сделать активным все поле как ссылку для открытия Аккордеона, не наводя на саму ссылку как в примере 1 на этой странице… ( Заголовок 1 панели )?
Александр Мальцев
Александр Мальцев
Посмотрите ответ в этом комментарии.
kasadas
kasadas
А почему мой вопрос удалили?
Александр Мальцев
Александр Мальцев
Никто вопрос не удалял, просто Вы его оставили не в этом месте, а вот здесь
HTML-код аккордеона
<nav class="panel panel-danger">
  <div class="panel-heading">
    <h5 class="panel-title">
      Название панели
    </h5>
  </div>
  <div class="panel-body">
    <div class="panel-group" id="panel">
     
      <div class="panel panel-default">
        <div class="panel-heading">
          <h6 class="panel-title">
            <a data-toggle="collapse" data-parent="#panel" href="#panel1">
              Название 1 панели
            </a>
          </h6>
        </div>
        <div id="panel1" class="panel-collapse collapse">
          <div class="panel-body">
            Содержимое 1 панели...
          </div>
        </div>
      </div>
     
      <div class="panel panel-default">
        <div class="panel-heading">
          <h6 class="panel-title">
            <a data-toggle="collapse" data-parent="#panel" href="#panel2">
              Название 2 панели
            </a>
          </h6>
        </div>
        <div id="panel2" class="panel-collapse collapse">
          <div class="panel-body">
            Содержимое 2 панели...
          </div>
        </div>
      </div>

    </div>
  </div>
</nav>

Аноним
Аноним
Добрый день,
у меня есть два блока, при нажатии на один второй должен быть скрытым, и наоборот при нажатии 2ого первый скрываться.

Как такое можно осуществить?

Александр Мальцев
Александр Мальцев
Здравствуйте.
Для этого необходимо написать код на JavaScript (+jQuery):
<div id="div1">
1
</div>
<div id="div2" style="display:none">
2
</div>

<script>
$(function(){
  $('#div1').click(function(){
    $(this).hide();
    $('#div2').show();
  });
  $('#div2').click(function(){
    $(this).hide();
    $('#div1').show();
  });  
});
</script>
Аноним
Аноним
Добрый день. Огромное спасибо за уроки все очень доходчиво и понятно.
У меня возник вопрос: как сделать так что бы данные списки в меню при загрузке страницы были закрыты (сейчас при загрузке страницы — 1ый список всегда открыт, после переходов уже все поочередно открывается и закрывается)
Аноним
Аноним
хотя уже все, разобрался надо просто убрать лишний класс
class="panel-collapse collapse in">
«IN»
Аноним
Аноним
Спасибо за помощь. Развития вам в Новом году.
Александр Мальцев
Александр Мальцев
Спасибо, Дмитрий.
Аноним
Аноним
Доброго дня, Александр!
подскажите как сделать чтобы активное (раскрытое) поле panel-heading подсвечивалось заданным цветом?
Александр Мальцев
Александр Мальцев
Здравствуйте, Дмитрий!
Это можно выполнить с помощью скрипта:
// после загрузки страницы
$(function() {
  // изменить цвет фона открытой panel-heading на активный
  $('#accordion .collapse.in').prev().css("backgroundColor", "#5be08d");
  // при открытии панели изменяем цвет фона panel-heading на активный
  $('#accordion .collapse').on('show.bs.collapse', function () {
    $(this).prev().css("backgroundColor", "#5be08d");
  })
  // при закрытии панели изменяет цвет фона на неактивный
  $('#accordion .collapse').on('hide.bs.collapse', function () {
    $(this).prev().css("backgroundColor", "#f5f5f5");
  })
});
Александр Мальцев
Александр Мальцев
Или лучше это сделать с помощью классов.
В этом случае скрипт будет такой:
$(function() {
  $('#accordion .collapse.in').prev().addClass("active-panel");
  $('#accordion .collapse').on('show.bs.collapse', function () {
    $(this).prev().addClass("active-panel");
  })
  $('#accordion .collapse').on('hide.bs.collapse', function () {
    $(this).prev().removeClass("active-panel");
  })
});
И соответственно необходимо добавить в CSS:
.active-panel {
  background-color: #5be08d !important;
}
Аноним
Аноним
Спасибо. Все время нет изучить JS и jQuery, пытался самостоятельно добавить класс к раскрытой панели, не получилось. Ну и у вас, естественно нашел, что искал.
Аноним
Аноним
Подскажите пожалуйста как эту штуку использовать в modx revo.
Александр Мальцев
Александр Мальцев
Если Вам нужно статический вывод то используйте её в шаблоне или чанке.
Если Вы хотите её формировать, то выберите для этого подходящий сниппет…
Аноним
Аноним
Привет
скажи а можно ли сделать чтобы свертывание и развертывание
происходило по нажатии по панели, сейчас по тексту в панели.
Александр Мальцев
Александр Мальцев
Привет, можно.

Для этого необходимо все data-атрибуты добавлять к заголовку панели.
Например:
<!-- 1 панель -->
<div class="panel panel-default">
  <!-- Заголовок 1 панели -->
  <div class="panel-heading" data-toggle="collapse" data-target="#collapseOne">
    <h4 class="panel-title">
      Заголовок панели
    </h4>
  </div>
  <div id="collapseOne" class="panel-collapse collapse in">
    <!-- Содержимое 1 панели -->
    <div class="panel-body">
      ...
    </div>
  </div>
</div>
Tracktor
Tracktor
Я так сделал, и теперь не срабатывает «аккордионность», то есть при открытии следующего блока предыдущий не закрывается… Что может быть не так?
Александр Мальцев
Александр Мальцев
Используйте атрибут data-parent, в качестве значения которого указывайте id родителя.
Например, как-то так:
<div class="panel-group" id="accordion">

<!-- 1 панель -->
<div class="panel panel-default">
  <!-- Заголовок 1 панели -->
  <div class="panel-heading" data-toggle="collapse" data-target="#collapseOne" data-parent="#accordion">
    <h4 class="panel-title">
      Заголовок панели 1
    </h4>
  </div>
  <div id="collapseOne" class="panel-collapse collapse in">
    <!-- Содержимое 1 панели -->
    <div class="panel-body">
      Текст панели 1...
    </div>
  </div>
</div>
<!-- 2 панель -->
<div class="panel panel-default">
  <!-- Заголовок 1 панели -->
  <div class="panel-heading" data-toggle="collapse" data-target="#collapseTwo" data-parent="#accordion">
    <h4 class="panel-title">
      Заголовок панели 2
    </h4>
  </div>
  <div id="collapseTwo" class="panel-collapse collapse">
    <!-- Содержимое 2 панели -->
    <div class="panel-body">
      Текст панели 2...
    </div>
  </div>
</div>
<!-- 3 панель -->
<div class="panel panel-default">
  <!-- Заголовок 3 панели -->
  <div class="panel-heading" data-toggle="collapse" data-target="#collapseThree" data-parent="#accordion">
    <h4 class="panel-title">
      Заголовок панели 3
    </h4>
  </div>
  <div id="collapseThree" class="panel-collapse collapse">
    <!-- Содержимое 3 панели -->
    <div class="panel-body">
      Текст панели 3...
    </div>
  </div>
</div>

</div>
Аноним
Аноним
При клике на кнопку «Collapse с параметром toggle» сворачивается и разворачивается не текст под ней, как это задумано, а вот этот текст «На этом примере показана возможность сворачивания и разворачивания элемента с помощью кода JavaScript. Нажмите на кнопку, чтобы увидеть этот эффект.» Находящийся выше нашей кнопки
Александр Мальцев
Александр Мальцев
Спасибо, Артём. Поправил код.
Аноним
Аноним
Здравствуйте!
Такая ситуация:
Одностраничный сайт.
Стандартное меню bootstrap.
При нажатии на пункт меню с мобильного, само меню не сворачивается, а остается поверх контента.
Видел решение, когда меню при раскрытии сдвигает контент, возможно есть какие то другие решения? Подскажите пожалуйста

Ссылка на скрин — yadi.sk/i/caHPBx4UiGWF8

<nav class="navbar navbar-default navbar-fixed-top">
      		<div  id="nav" class="container">
        	<div class="navbar-header">
           		 <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">

            	<span class="sr-only">Открыть навигацию</span>
            	<span class="icon-bar"></span>
            	<span class="icon-bar"></span>
            	<span class="icon-bar"></span>
          		</button>

        	</div>
        <div class="navbar-collapse collapse" id="navbar" >
          <ul class="nav navbar-nav">
            <li><a class ="a_nav" href="/">Главная</a></li>
            <li><a class ="a_nav" href="#screen1">Как это работает</a></li>
            <li><a class ="a_nav" href="#screen2">Зачем это мне</a></li>
            <li><a class ="a_nav" href="#screen3">О компании</a></li>
            <li><a class ="a_nav" href="#screen4">Контакты</a></li>
            
            </ul>
 			<ul class="nav navbar-nav navbar-right">
 				<li class="tel">8 (499) 372-04-72</li>
        		<li><a href="https://www.youtube.com/channel/UC2URwxPq11yfNqalOqlmLKQ" target = _blank><i class="fa fa-youtube-square fa-lg fa-circle"></i></a></li>
            <li><a href="http://vk.com/hsatraining" target = _blank><i class="fa fa-vk fa-lg fa-circle"></i></a></li>
      		</ul>

        </div>
      </div>
</nav>	

Александр Мальцев
Александр Мальцев
Здраствуйте.
В Twitter Bootstrap такая настройка выставлена по умолчанию. Т.е. когда Вы нажимаете на пункт меню, оно остаётся открытым.
Для того чтобы данное меню можно было использовать на одностраничных сайтах можно воспользоваться следующим решением (т.е. оно будет сворачиваться всякий раз, когда пользователь нажимает на пункт, содержащий ссылку):
$(function() {
  $(document).on('click','.navbar-collapse.in',function(e) {
    if( $(e.target).is('a') && $(e.target).attr('class') != 'dropdown-toggle' ) {
      $(this).collapse('hide');
    }
  });
});
Меню на сайтах также можно выполнить в виде кнопок, расположенных горизонтально или вертикально. Кроме этого очень часто на сайтах еще используют выезжающие меню с левой или правой стороны.
Аноним
Аноним
Огромное спасибо! У Вас отличный ресурс. Добавил в закладки
Аноним
Аноним
Весьма доходчиво. Однако, как сделать этот аккордеон вертикальным? это возможно с панелями или есть альтернативный вариант?
Александр Мальцев
Александр Мальцев
Так просто его переделать не получится. Появится время, попробую поэкспериментировать с панелями и сообщу Вам результат.

А пока можете поискать их в интернете, там их достаточно много…
Александр Мальцев
Александр Мальцев
Можно сделать так.
Код CSS:
article.accordion {
  display: block; overflow: auto; width: 663px; margin: 0 auto; 
}
article.accordion section {
  position: relative; display: block; float: left; width: 37px; height: 300px; margin: 3px 0 3px 3px;
  color: #337AB7; background-color: #337AB7; overflow: hidden; border-radius: 3px; border: 1px solid #337AB7; 
}
article.accordion section h2 {
  position: absolute; font-size: 16px; width: 300px; height: 37px; top: 300px; left: 0; text-indent: 1em;
  padding: 0; margin: 0; color: #fff; -webkit-transform-origin: 0 0; -moz-transform-origin: 0 0; -ms-transform-origin: 0 0; -o-transform-origin: 0 0; transform-origin: 0 0; -webkit-transform: rotate(-90deg); -moz-transform: rotate(-90deg); -ms-transform: rotate(-90deg); -o-transform: rotate(-90deg); transform: rotate(-90deg);
}
article.accordion section h2 a {
  display: block; width: 100%; line-height: 37px; text-decoration: none; color: inherit; outline: 0 none;
}
article.accordion section:target {
  width: 500px; padding: 0 15px; color: #333; background-color: #fff; 
}
article.accordion section:target h2 {
  position: static; font-size: 16px; text-indent: 0; color: #333; -webkit-transform: rotate(0deg);   -moz-transform: rotate(0deg); -ms-transform: rotate(0deg); -o-transform: rotate(0deg); transform: rotate(0deg);
}
article.accordion section, article.accordion section h2 {
  -webkit-transition: all 0.3s ease; -moz-transition: all 0.3s ease; -ms-transition: all 0.3s ease;   -o-transition: all 0.3s ease; transition: all 0.3s ease;
}
Код HTML:
<article class="accordion">
  <section id="acc1">
    <h2><a href="#acc1">Раздел 1</a></h2>
    <p>...</p>
  </section>
  <section id="acc2">
    <h2><a href="#acc2">Раздел 2</a></h2>
    <p>...</p>
  </section>
  <section id="acc3">
    <h2><a href="#acc3">Раздел 3</a></h2>
    <p>...</p>
  </section>
  <section id="acc4">
    <h2><a href="#acc4">Раздел 4</a></h2>
    <p>...</p>
  </section>
  <section id="acc5">
    <h2><a href="#acc5">Раздел 5</a></h2>
    <p>...</p>
  </section>
</article>
Аноним
Аноним
Подскажите пожалуйста что не так в этом куске кода?

Панель отображается открытой, но при нажатии не сворачивается/разворачивается.
<div class="panel panel-default"> 
      <div class="panel-heading"> 
        <h4 class="panel-title"> <a class="accordion-toggle" href="#accordion1_2" target="_parent" > 2.1. Вопрос-Ответ </a></h4>
       </div>
     
      <div id="accordion1_2" class="panel-collapse collapse in"> 
        <div class="panel-body"> 
          <p>Q: Как сделать пересчет суммы в корзине?</p>
         
          <p>A: После редактирования списка товаров нажмите на кнопку "Пересчитать"</p>
         
          <ul> </ul>
         </div>
       </div>
     </div>

Александр Мальцев
Александр Мальцев
Необходимо добавить к элементу a атрибут data-toggle=«collapse».
...
<a data-toggle="collapse" class="accordion-toggle" href="#accordion1_2" target="_parent">
...