JS

ネイティブネタ帳

UI

モーダル

タブ

ドロワー

スライダー

スクロール

アコーディオン

目次

ローディングアニメーション

ツールチップ

ヘッダー

テーブル

グラフ

背景

フォーム

フォーム

文字

文字の装飾

文字の操作

文字のカウント

数字の操作

ウィンドウ

ウィンドウ操作

タイトルの操作

ページ遷移時の動き

class

classの操作

要素

要素の操作

要素の追加

API

WP REST API

Google Books APIs

楽天市場API

openBD

画像・動画

画像の操作

YouTube

リンク

Google Analytics

cookie

検索

検索

お気に入り登録

JavaScriptの.classList.toggle()でツリー構造のアコーディオン

お気に入り登録をすると、お気に入り記事一覧に登録することができます。

.classList.toggle()

JavaScriptの.classList.toggle()でツリー構造のアコーディオン

JavaScriptの.classList.toggle()でツリー構造のアコーディオン

今回は、ツリー構造のブロックを、アコーディオンのように「クリックで表示・非表示の切り替え」で表示させてみます。

CSSのチェックボックスを使って実装できる内容ですが、JavaScriptを使いHTMLもスッキリさせたコードです。

.classList.toggle()

JavaScriptの .classList.toggle() は、タグが持つclassをON・OFFで切り替えるメソッドです。

element.classList.toggle('class名')

個人的にもよく使うメソッドです。

この記事では、.addEventListener のクリックイベントと併用しています。

ツリー構造のアコーディオンサンプル

早速サンプルです。

デフォルトで「関東地方」と表示されていますが、その要素をクリックすると「群馬県」「茨城県」の小階層が表示され、そのまたさらに「東京都」をクリックするとその下の23区が表示されます。

  • 関東地方
    • 群馬県
    • 茨城県
    • 東京都
      • 新宿区
      • 渋谷区
      • 杉並区
        • 桃井
        • 宮前
        • 永福
        • 井草
      • 中野区
      • 八王子市
    • 千葉県

展開されたものは再度クリックすると折り畳みされ、また非表示になります。

かかかず
かかかず

アコーディオンのように表示・非表示が切り替わります。

実装の手順と方法

手順と方法

それぞれのコードの解説の前に、実装の手順と方法について簡単にご説明します。

HTMLを記述

はじめに、設置したい場所へ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を記述

次に、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を記述

最後に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は、入れ子で使う「カテゴリー表示」にも使えます。

多数の入れ子構造で表示スペースが限られている場合にマッチするので、その時にでも使ってみてください。