マルチレベルのアコーディオンとは、例えば「アコーディオンxアコーディオン」のように、各レベルをクリックすると、徐々にそれぞれの新しいレベルが表示されるアコーディオンです。
そんなマルチレベルのアコーディオンを、ネイティブなJavaScriptで作ってみました。
目次
.querySelectorAll()
.querySelectorAll()
は、指定したセレクタの条件と一致したHTML要素を全て配列で返します。そして、一致するものがない場合は、空のNodeListを返します。
.querySelectorAll(CSSのセレクタ);
書き方は上記のようにして、引数にCSSのセレクタをして使用します。
複数のセレクタを指定して「AND」で絞り込む
複数のセレクタを指定して「AND」で絞り込む場合は、セレクタ内の記述に半角空白で記述すればOKです。
以下は、p
タグと「title」のclass名がついた要素を指定した場合です。
document.querySelectorAll("p .title");
複数のセレクタを指定して「OR」で絞り込む
複数のセレクタを「OR」で絞り込む場合は、カンマで区切ればOKです。
document.querySelectorAll(".title1,.title2");
上記は、「title1」と「title2」のclassでどちらかが一致した場合の記述です。
このように複数指定できるのも.querySelectorAll
の便利な特徴です。
.querySelectorAll()を使ったマルチレベルアコーディオンのサンプル
青字のテキストはリンクで、黒字のテキストはアコーディオン開閉のタイトルです。
マルチレベルアコーディオンのコード
HTMLは、cateTitle
のclass名がついているdivタグがアコーディオンタイトルになっています。
そして、このdivタグをクリックすると、同じ階層にある ul
タグ以下のオブジェクトが表示される仕組みです。
<div class="javaSample">
<ul class="catBlock">
<li><a href="#">親アコーディオン1</a></li>
<li>
<div class="cateTitle">
<p>親アコーディオン2</p>
</div>
<ul class="childCat">
<li><a href="#">子リンク2-1</a></li>
<li><a href="#">子リンク2-2</a></li>
</ul>
</li>
<li>
<div class="cateTitle">
<p>親アコーディオン3</p>
</div>
<ul class="childCat">
<li><a href="#">子リンク3-1</a></li>
<li><a href="#">子リンク3-2</a></li>
<li>
<div class="cateTitle">
<p>子アコーディオン3-1</p>
</div>
<ul class="grandChildCat">
<li><a href="#">孫リンク3-1</a></li>
<li><a href="#">孫リンク3-2</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
CSSのアコーディオンだと、HTMLがごちゃつきやすいですが、JSならHTMLは簡単な記述ですみます。
JavaScriptは、.querySelectorAll()
で指定した「cateTitle」がクリックされると、.nextElementSibling
で同じ親要素を持って隣接する次の要素の display
プロパティの「none」を「block」で表示を切り替える仕組みです。
var acc = document.querySelectorAll(".cateTitle");
var i;
for ( i = 0; i < acc.length; i++ ){
acc[i].onclick = function() {
this.classList.toggle('active');
var panel = this.nextElementSibling;
if ( panel.style.display ){
panel.style.display = null;
} else {
panel.style.display = "block";
panel.style.opacity = 1;
}
}
}
CSS
JavaScriptで表示・非表示を切り替えるので、CSSはシンプルです。
格納されているアコーディオンの子と孫は、最初非表示の状態にする為display: none;
で非表示にしています。
div.cateTitle, ul.childCat li {
display: block;
line-height: 1.6;
border: none;
cursor: pointer;
transition: 0.5s ease-in;
position: relative;
margin: 0;
padding: 5px 40px 5px 15px;
}
div.cateTitle.active {
margin-bottom: 0;
}
ul.childCat, ul.grandChildCat {
display: none;
overflow:hidden;
opacity: 0;
animation: show 0.6s linear 0s;
}
div.cateTitle:after {
color: #2165c0;
position: absolute;
right: 15px;
top: 50%;
transform: translateY(-50%);
font-family: "Font Awesome 5 Free";
font-weight: 900;
font-size: 1em;
content: "\f055";
}
div.cateTitle.active:after {
content: "\f056";
}
@keyframes show{
from{
opacity: 0;
}
to{
opacity: 1;
}
}
特に、display: none;
のアコーディオンに格納している要素をクリックで表示させる場合、CSSのtransition
で徐々に表示させようと思うとうまくいきません。
その為、@keyframes
でアニメーションを指定して表示させています。
アコーディオンを展開する「+」アイコンは、FontAwesomeを使っているのでご注意ください。