Создайте эксклюзивный аккордеон с несколькими элементами <details>
с одинаковыми name
.
Аккордеон
Распространенным шаблоном пользовательского интерфейса в Интернете является компонент «аккордеон». Это компонент, состоящий из нескольких виджетов раскрытия, которые по отдельности можно развернуть (или свернуть), чтобы показать (или скрыть) их содержимое.
Чтобы реализовать этот шаблон в Интернете, вы объединяете несколько элементов <details>
и обычно группируете их визуально, чтобы указать, что они принадлежат друг другу.
Эксклюзивный аккордеон
Browser Support
Разновидностью шаблона аккордеона является эксклюзивный аккордеон , в котором одновременно можно открыть только один из виджетов раскрытия.
Чтобы создать эксклюзивный аккордеон в Интернете, вы добавляете атрибут name
к элементам <details>
. При использовании этого атрибута несколько элементов <details>
с одинаковым значением name
образуют семантическую группу и будут вести себя как эксклюзивный аккордеон. Когда вы открываете один из элементов <details>
из группы, ранее открытый автоматически закроется.
<details name="learn-css"> <summary>Welcome to Learn CSS!</summary> <p>…</p> </details> <details name="learn-css"> <summary>Box Model</summary> <p>…</p> </details> <details name="learn-css"> <summary>Selectors</summary> <p>…</p> </details>
На странице может быть несколько эксклюзивных аккордеонов. Всякий раз, когда вы используете новое значение name
в элементе <details>
, создается новая логическая группа.
Элементы <details>
, являющиеся частью эксклюзивного аккордеона, не обязательно должны быть родственными. Их можно разбросать по документу. Их группирует атрибут name
, а не порядок DOM.
Polyfill эксклюзивный аккордеон
С помощью следующего JavaScript можно полифиллить поведение эксклюзивного аккордеона. Код основан на событии toggle
элемента <details>
.
Когда открывается элемент <details>
с name
, код находит другие открытые элементы <details>
с тем же значением атрибута name
и закрывает их.
document.querySelectorAll("details[name]").forEach(($details) => { $details.addEventListener("toggle", (e) => { const name = $details.getAttribute("name"); if (e.newState == "open") { document .querySelectorAll(`details[name=${name}][open]`) .forEach(($openDetails) => { if (!($openDetails === $details)) { $openDetails.removeAttribute("open"); } }); } }); });
Некоторые старые версии браузеров не вызывают это событие toggle
. В этих браузерах код полифила ничего не сделает. С точки зрения прогрессивного улучшения это приемлемое поведение.