今回は、ツリー構造のブロックを、アコーディオンのように「クリックで表示・非表示の切り替え」で表示させてみます。
CSSのチェックボックスを使って実装できる内容ですが、JavaScriptを使いHTMLもスッキリさせたコードです。
.classList.toggle()
JavaScriptの .classList.toggle()
は、タグが持つclassをON・OFFで切り替えるメソッドです。
element.classList.toggle('class名')
個人的にもよく使うメソッドです。
この記事では、.addEventListener
のクリックイベントと併用しています。
ツリー構造のアコーディオンサンプル
早速サンプルです。
デフォルトで「関東地方」と表示されていますが、その要素をクリックすると「群馬県」「茨城県」の小階層が表示され、そのまたさらに「東京都」をクリックするとその下の23区が表示されます。
- 関東地方
- 群馬県
- 茨城県
- 東京都
- 新宿区
- 渋谷区
- 杉並区
- 桃井
- 宮前
- 永福
- 井草
- 中野区
- 八王子市
- 千葉県
展開されたものは再度クリックすると折り畳みされ、また非表示になります。
アコーディオンのように表示・非表示が切り替わります。
実装の手順と方法
それぞれのコードの解説の前に、実装の手順と方法について簡単にご説明します。
はじめに、設置したい場所へHTMLを記述します。この記事のHTMLは以下の通りです。
<ul id="listBlock">
<li><span class="listIn">関東地方</span>
<ul class="nested">
<li>群馬県</li>
<li>茨城県</li>
<li><span class="listIn">東京都</span>
<ul class="nested">
<li>新宿区</li>
<li>渋谷区</li>
<li><span class="listIn">杉並区</span>
<ul class="nested">
<li>桃井</li>
<li>宮前</li>
<li>永福</li>
<li>井草</li>
</ul>
</li>
<li>中野区</li>
<li>八王子市</li>
</ul>
</li>
<li>千葉県</li>
</ul>
</li>
</ul>
次に、JavaScriptのコードをページに記述します。これは、Swiperの動き方を指定するオプションです。
コードは <body>〜</body>
で、</body>
の閉じタグ(クロージングタグ)の前に記述しましょう。
var toggler = document.getElementsByClassName("listIn");
for (i = 0; i < toggler.length; i++) {
toggler[i].addEventListener("click", function() {
this.parentElement.querySelector(".nested").classList.toggle("active");
this.classList.toggle("listIn-down");
});
}
最後にCSSを記述して、見た目を整えます。
#listBlock, #listBlock li {
margin: 0;
padding: 2px 0;
border: none;
list-style: none;
}
#listBlock ul {
list-style: none;
margin: 0;
padding-top: 0;
padding-bottom: 0;
padding-left: 16px;
}
.listIn {
cursor: pointer;
user-select: none;
display: block;
}
.listIn:hover {
background: #eee;
}
.listIn::before {
content: "\25B6";
color: black;
display: inline-block;
margin-right: 6px;
opacity: 0.25;
font-size: 0.7rem;
vertical-align: middle;
transition: 0.1s ease-in-out;
}
.listIn.listIn-down {
font-weight: 600;
}
.listIn-down::before {
transform: rotate(90deg);
}
.nested {
display: none;
}
.active {
display: block;
}
これで完成です。
ざっくりとしたコードの解説
HTML
HTMLは、ul
を使ったリストタグで、子階層がある親要素の li
タグの中に「<span class="listIn">〜〜〜〜</span>
」を記述して、その中に「nested」のclass名を持つ ul
タグを記述しています。
<ul id="listBlock">
<li><span class="listIn">関東地方</span>
<ul class="nested">
<li>群馬県</li>
<li>茨城県</li>
<li><span class="listIn">東京都</span>
<ul class="nested">
<li>新宿区</li>
<li>渋谷区</li>
<li><span class="listIn">杉並区</span>
<ul class="nested">
<li>桃井</li>
<li>宮前</li>
<li>永福</li>
<li>井草</li>
</ul>
</li>
<li>中野区</li>
<li>八王子市</li>
</ul>
</li>
<li>千葉県</li>
</ul>
</li>
</ul>
似たようなタグが複数あるので、多少可読性が悪いかもしれませんが、このように簡単な構造のコードです。
JavaScript
JavaScriptは、 はじめにdocument.getElementsByClassName("listIn")
で「listIn」のclass名が付く要素を全て取得します。
var toggler = document.getElementsByClassName("listIn");
for (i = 0; i < toggler.length; i++) {
toggler[i].addEventListener("click", function() {
this.parentElement.querySelector(".nested").classList.toggle("active");
this.classList.toggle("listIn-down");
});
}
取得したら、ループを回して「listIn」の要素がクリックされたら「nested」のclass名を持つ要素に「active」のclass名を付与して、アコーディオンが展開します。
.classList.toggle
でクリック毎にclass名を追加・削除します。
コード自体もシンプルで、動作も想像しやすい記述内容です。
CSS
CSSのコードはそんなに多くはありません。
アコーディオンで展開できる要素は、before
の擬似要素で「▶︎」を表示させ、クリックでclass名が付与されることで、transform: rotate(90deg)
の変形で下方向の三角に変形させています。
#listBlock, #listBlock li {
margin: 0;
padding: 2px 0;
border: none;
list-style: none;
}
#listBlock ul {
list-style: none;
margin: 0;
padding-top: 0;
padding-bottom: 0;
padding-left: 16px;
}
.listIn {
cursor: pointer;
user-select: none;
display: block;
}
.listIn:hover {
background: #eee;
}
.listIn::before {
content: "\25B6";
color: black;
display: inline-block;
margin-right: 6px;
opacity: 0.25;
font-size: 0.7rem;
vertical-align: middle;
transition: 0.1s ease-in-out;
}
.listIn.listIn-down {
font-weight: 600;
}
.listIn-down::before {
transform: rotate(90deg);
}
.nested {
display: none;
}
.active {
display: block;
}
さいごに
表示に「クリック」のストレスが多少ありますが、ツリー構造のUIは、入れ子で使う「カテゴリー表示」にも使えます。
多数の入れ子構造で表示スペースが限られている場合にマッチするので、その時にでも使ってみてください。