👻

【JS】タブの切り替えをVanilla JS でやってみる

2022/11/30に公開

概要

jQueryを使用していたこともあり、以前Vanilla JSに書き換えていたのをせっかくなので、Zennに残したいと思って、忘備録としてメモ。

実装

サンプルとして、以下のような感じです。

内容としては、タブとコンテンツがあって、タブが選択されてる状態は「active」クラスが付与されていて、表示されているコンテンツは「show」というクラスが付与されている。

html

CSSは「active」「show」クラスの切り替えの話なので省きますが、htmlの構造は下記です。

<!-- タブ -->
<ul class="tab-list">
  <li class="tab-list__item active">タブA</li>
  <li class="tab-list__item">タブB</li>
  <li class="tab-list__item">タブC</li>
</ul>

<!-- タブコンテンツ  -->
<div class="tab-contents">
  <div class="tab-contents__item show">
    タブコンテンツA
  </div>
  <div class="tab-contents__item">
    タブコンテンツB
  </div>
  <div class="tab-contents__item">
    タブコンテンツC
  </div>
</div>

最初に表示する要素にはあらかじめ、それぞれ「active」と「show」クラスを付与しておく。
ポイントとしては、「タブA」と「コンテンツA」などはインデックス番号が同じになるようにする。

Javascript

今回のポイントとなるjavascriptの部分。
querySelectorAllでタブとコンテンツの要素を取得して、各タブにクリックイベントを設定しておくのは、説明は特になし。


// タブとコンテンツの要素を取得
const tabList = document.querySelectorAll(".tab-list__item");
const tabContent = document.querySelectorAll(".tab-contents__item");

//DOMが読み込み
document.addEventListener("DOMContentLoaded", function () {

//各タブにクリックイベントを設定
  for (let i = 0; i < tabList.length; i++) {
    tabList[i].addEventListener("click", tabSwitch);
  }

  function tabSwitch() {
  
    // 1:activeクラスを持っている要素からactiveクラスを削除
    document.querySelectorAll(".active")[0].classList.remove("active");
    
    //2:クリックしたタブにactiveクラスを付与
    this.classList.add("active");
    
    //3:showクラスを持っている要素からshowクラスを削除
    document.querySelectorAll(".show")[0].classList.remove("show");

    //4:タブを配列にする
    let tabArr = Array.from(tabList);
    //以下の方法も有名
    let tabArr = Array.prototype.slice.call(tabList);

    //5:クリックしたタブのインデックス番号を取得
    let index = tabArr.indexOf(this);
    
   
    //6:タブのインデックスから同じインデックスのコンテンツにshowクラスを付与する
    tabContent[index].classList.add("show");
  }
});

上記のクリックして実行する関数tabSwitchについて。

querySelectorAll(".active")[0]querySelectorAll(".show")[0]を指定しているが、こちらはどちらのクラスも1つしか付与されていないこと前提なので、0番のインデックスを指定している。もしくは以下のようにタブとコンテンツをループ処理することで同じように削除できる。

// tabItemとtabContentの.activeを削除する
  for (let i = 0; i < tabList.length; i++) {
    tabList[i].classList.remove('active');
  }
  for (let i = 0; i < tabContent.length; i++) {
    tabContent[i].classList.remove('active');
  }

今回、ポイントとなる部分は4,5,6の部分。

まずクリックしたタブのインデックス番号を知りたいが、querySelectorAllでリストの要素を取得したが、こちらは配列ではないので配列の処理ができない。
https://chaika.hatenablog.com/entry/2019/09/09/083000

その為、一旦配列にしたいのでArray.fromを使って配列に。
もしくは、Array.prototype.slice.callを使う。こちらは昔からのあるある。

配列にした後はindexOfメソッドを使って引数にクリックした要素(this)を指定することでインデックス番号を取得できる。

https://www.start-point.net/blog/web/javascript/indexof/

あとはコンテンツ(tabContent)に取得したインデックス番号を指定してあげれば、その要素にshowクラスを付与してあげればよい。

まとめ

以上で、タグの切り替え処理をVanilla JS での処理を防備ログ。
この手の記事はネットで検索すればたくさんでてくる。

今後もちょこちょこVanilla JSでの処理を忘備録として残していく予定。

Discussion