detailsを使ったアコーディオンの実装が度々あるので、JavaScriptを使った開閉時のアニメーションの実装をメモしておきます。
サンプルコード
HTMLはアコーディオンと見出し、パネルの3つにJavaScript用のclassを付与します。
<details class="accordion js-accordion">
<summary class="accordion_head js-accordion-head">アコーディオンの見出し</summary>
<div class="accordion_body js-accordion-body">
<div class="accordion_inner">
<p>アコーディオンの内容</p>
</div>
</div>
</details>
アコーディオンのパネル部分にアニメーション用のスタイルを設定します。
.accordion_body {
overflow: hidden;
}
最後にJavaScriptです。
アニメーション部分はWeb Animations APIを使っていますが、詳しくは以前に記事を投稿していますのでそちらをご確認ください。
document.addEventListener('DOMContentLoaded', () => {
const $accordions = document.querySelectorAll('.js-accordion');
const accordionSlideOptions = {
duration: 500,
easing: "ease"
}
$accordions.forEach($accordion => {
const $accordionHead = $accordion.querySelector('.js-accordion-head');
const $accordionBody = $accordion.querySelector('.js-accordion-body');
$accordionHead.addEventListener('click', (e) => {
e.preventDefault();
// detailsが閉じている場合
if(!$accordion.open) {
$accordion.open = true;
$accordionBody.animate({
height: ['0px', `${$accordionBody.scrollHeight}px`]
}, accordionSlideOptions);
// detailsが開いている場合
} else {
const closeAnimation = $accordionBody.animate({
height: [`${$accordionBody.scrollHeight}px`, '0px']
}, accordionSlideOptions);
// 閉じるアニメーション完了後にopen属性を除去
closeAnimation.addEventListener('finish', function() {
$accordion.open = false;
});
}
});
});
});
アニメーション処理中はopen属性を付与した状態にする必要があるため、デフォルトのdetailsの処理は止めた上でJavaScriptで付け替えを行っています。
detailsの開閉アニメーションのデモページ
コメントが承認されるまで時間がかかります。