JavaScript(jQuery未使用)を使ってヌルッと表示されるアコーディオンメニューを作成する。
デモと解説
デモ
タイトル帯をクリックするとアコーディオンの中身が出てきます。
See the Pen Untitled by kitaharas (@kitaharas) on CodePen.
解説(JS)
全文:JS
const accordionItems = document.querySelectorAll('.accordion-item');
accordionItems.forEach(item => {
const header = item.querySelector('.accordion-header');
const content = item.querySelector('.accordion-content');
header.addEventListener('click', () => {
const isActive = item.classList.contains('active');
const activeItem = document.querySelector('.accordion-item.active');
if (activeItem && activeItem !== item) {
const activeItemContent = activeItem.querySelector('.accordion-content');
activeItem.classList.remove('active');
activeItemContent.style.maxHeight = 0;
}
if (!isActive) {
item.classList.add('active');
content.style.maxHeight = content.scrollHeight + "px";
} else {
item.classList.remove('active');
content.style.maxHeight = 0;
}
});
});
解説
const accordionItems = document.querySelectorAll('.accordion-item');
accordionItems.forEach(item => {
const header = item.querySelector('.accordion-header');
const content = item.querySelector('.accordion-content');
header.addEventListener('click', () => {
複数あるアコーディオンそれぞれに、’.accordion-header’をクリックしたら’.accordion-content’を開く。というイベントをあらかじめ仕込んでおきたいので、querySelectorAllで取得し、forEachでループします。
「’.accordion-header’をクリックしたら〜」は’header.addEventListener(‘click’, () => {‘ から始まっています。
const isActive = item.classList.contains('active');
const activeItem = document.querySelector('.accordion-item.active');
‘const isActive’はアコーディオン(item)が’active’かどうかを定義。
‘const activeItem’は全体で既に’active’になっている要素を取得し定義します。(nullの場合もある)
if (activeItem && activeItem !== item) {
const activeItemContent = activeItem.querySelector('.accordion-
content');
activeItem.classList.remove('active');
activeItemContent.style.maxHeight = 0;
}
既にactiveになっている要素が存在し、且つその要素がクリックされた’header’を含む’item’要素では無い場合、
既にactiveになっている要素からactiveを外し、その要素内の’.accordion-content’のmax-heightを0にします。
(アコーディオンを閉じる。)
if (!isActive) {
item.classList.add('active');
content.style.maxHeight = content.scrollHeight + "px";
} else {
item.classList.remove('active');
content.style.maxHeight = 0;
}
クリックされた要素がactiveでなければ、max-heightを要素の高さ分付与します。(開く)
クリックされた要素がactiveであれば、max-heightを0にします。(閉じる)
解説(CSS・HTML)
全文:CSS
.accordion {
display: flex;
flex-direction: column;
align-items: center;
}
.accordion-item {
width: 100%;
max-width: 600px;
margin-bottom: 20px;
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1);
border-radius: 4px;
overflow: hidden;
}
.accordion-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px;
background-color: #f4f4f4;
cursor: pointer;
transition: background-color 0.3s ease;
}
.accordion-content {
background-color: #fff;
overflow: hidden;
max-height: 0;
transition: max-height 0.5s cubic-bezier(0.445, 0.05, 0.55, 0.95);
}
.accordion-content p{
word-break: break-word;
}
.accordion-item.active .accordion-content {
max-height: 1000px;
transition-timing-function: cubic-bezier(0.445, 0.05, 0.55, 0.95);
}
.accordion-item.active .accordion-header {
background-color: #e1e1e1;
}
全文:HTML
<div class="accordion">
<div class="accordion-item">
<div class="accordion-header">Item1Title</div>
<div class="accordion-content">
<p>
Content1Content1Content1Content1Content1Content1Content1Content1Content1Content1Content1Content1Content1Content1Content1Content1Content1Content1Content1Content1Content1Content1Content1Content1Content1Content1
</p>
</div>
</div>
<div class="accordion-item">
<div class="accordion-header">Item2Title</div>
<div class="accordion-content">
<p>
Content2Content2Content2Content2Content2Content2Content2Content2Content2Content2Content2Content2Content2Content2Content2Content2Content2Content2Content2Content2Content2Content2Content2Content2Content2Content2Content2Content2Content2Content2
</p>
</div>
</div>
</div>
解説
特段これといって解説するところは無いですが、JSで要素の高さを動的に付与するようにしているので、それに合わせてぬるぬる動くようにtransitionを設定したりしています。
クリックした親要素にactiveが付与されるようにしているので、子要素の装飾は指定しやすいのでは無いかと思われます。
まとめ
以上、JavaScriptでアコーディオンメニューの実装でした。
まだまだ勉強中なのでもっとこういう風に書いたら簡単に書けるよ〜。っていうのがあったら是非教えて欲しいです!
コメント