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

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

UI

  • 他のウィンドウが開くことができないポップアップのUIです。

    モーダル

    モーダル

  • 並列な関係を持つ情報を1つずつ格納するUIです。

    タブ

    タブ

  • サイドから全体を覆うほど大きいメニュー表示するUIです。

    ドロワー

    ドロワー

  • 画像などのコンテンツをスライド表示させるUIです。

    スライダー

    スライダー

  • スクロールで表示が変化するスニペットです。

    スクロール

    スクロール

  • クリックすると隠れていた部分が開閉するUIです。

    アコーディオン

    アコーディオン

  • ページのhタグを取得して目次を生成するスニペットです。

    目次

    目次

  • ページの読み込み時にアニメーションをするスニペットです。

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

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

  • マウスオーバーした際に表示される補足説明です。

    ツールチップ

    ツールチップ

  • ページ内上部にあるナビゲーションUIです。

    ヘッダー

    ヘッダー

  • 行と列の組み合わせでできているUIです。

    テーブル

    テーブル

  • データを表やグラフで可視化して見せるUIです。

    グラフ

    グラフ

  • 背景をアニメーションで動かすスニペットです。

    背景

    背景

  • 短いテキスト情報をスクロール表示するUIです。

    ニュースティッカー

    ニュースティッカー

フォーム

  • ラジオボタン、チェックボックス、ドロップダウンリストなどを通じて、ユーザーが入力できるUIです。

    フォーム

    フォーム

文字

  • 文字列をJavaScriptで装飾・動きをつけるスニペットです。

    文字の装飾

    文字の装飾

  • 文字列の操作をして、置換・変更を行うスニペットです。

    文字の操作

    文字の操作

  • 文字列をカウントして表示などを行うスニペットです。

    文字のカウント

    文字のカウント

  • 数字の要素を取得して、変更するスニペットです。

    数字の操作

    数字の操作

ウィンドウ

classの操作

  • 要素を取得して、classを追加・削除するスニペットです。

    classの操作

    classの操作

要素の操作

API

  • WordPressのAPIを取得して表示するスニペットです。

    WP REST API

    WP REST API

  • Google Books APIsで書籍の情報を表示するスニペットです。

    Google Books APIs

    Google Books APIs

  • 楽天市場のAPIを取得して表示するスニペットです。

    楽天市場API

    楽天市場API

  • openBDのAPIを取得して表示するスニペットです。

    openBD

    openBD

画像・動画

  • 画像を取得して、アニメーションなどの変化を加えるスニペットです。

    画像の操作

    画像の操作

  • YouTubeの動画を表示するスニペットです。

    YouTube

    YouTube

リンク

  • ページ内のリンクを取得して変更・操作するスニペットです。

    リンク

    リンク

  • Google Analyticsとの連携をするスニペットです。

    Google Analytics

    Google Analytics

cookie

  • ブラウザのcookieを利用するスニペットです。

    cookie

    cookie

検索

  • 指定した要素の中から検索を行うスニペットです。

    検索

    検索