jsでタブメニューを作る

ページ内で、複数のタブを設置してクリックで内容を切り替える構造を、JavaScriptを使用して作成します。

参考ページ: https://tonoblog.yutaka01.net/2022/08/14/javascript__tab-menu/

HTMLを書く

<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>タブメニュー</title>
  <link rel="stylesheet" href="css/style.css">
</head>

<body>
  <div class="tab">
    <ul class="tab_menu">
      <li class="tab_menu-item is-active" data-tab="01">menu1</li>
      <!-- /.tab_menu-item -->
      <li class="tab_menu-item" data-tab="02">menu2</li>
      <!-- /.tab_menu-item -->
      <li class="tab_menu-item" data-tab="03">menu3</li>
      <!-- /.tab_menu-item -->
    </ul>
    <!-- /.tab_menu -->
    <div class="tab_panel">
      <div class="tab_panel-box tab_panel-box001 is-show" data-panel="01">
        <p class="tab_panel-text">初期表示のタブ内容 初期表示のタブ内容 初期表示のタブ内容 初期表示のタブ内容</p>
        <!-- /.tab_panel-text -->
      </div>
      <!-- /.tab_panel-box tab_panel-box001 -->
      <div class="tab_panel-box tab_panel-box002" data-panel="02">
        <p class="tab_panel-text">2枚目のタブ内容 2枚目のタブ内容 2枚目のタブ内容 2枚目のタブ内容</p>
        <!-- /.tab_panel-text -->
      </div>
      <!-- /.tab_panel-box tab_panel-box002 -->
      <div class="tab_panel-box tab_panel-box003" data-panel="03">
        <p class="tab_panel-text">3枚目のタブ内容 3枚目のタブ内容 3枚目のタブ内容 3枚目のタブ内容</p>
        <!-- /.tab_panel-text -->
      </div>
      <!-- /.tab_panel-box tab_panel-box003 -->
    </div>
    <!-- /.tab_panel -->
  </div>
  <!-- /.tab -->

  <script src="js/index.js"></script>
</body>

</html>

is-activeクラスでアクティブな状態のパネルにスタイルを指定します。

cssを設定します。

@charset "UTF-8";
.tab {
  max-width: 800px;
  margin: 0 auto;
  margin-top: 120px;
}
.tab_menu {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  min-height: 50px;
  padding: 0;
  margin: 0;
}
.tab_menu-item {
  list-style: none;
  width: 200px;
  padding: 8px 5px;
  text-align: center;
  margin-right: 6px;
  background-color: #cdcdcd;
  border-top-left-radius: 10px;
  border-top-right-radius: 10px;
  cursor: pointer;
  transition: all 0.3s;
}
.tab_menu-item:last-of-type {
  margin-right: 0;
}
.tab_menu-item.is-active {
  background-color: blue;
  color: #fff;
  padding: 12px 5px;
}
.tab_panel {
  width: 100%;
}
.tab_panel-box {
  min-height: 400px;
  /*テキスト量増加に対応 */
  padding: 10px 30px;
  border-radius: 10px;
}
.tab_panel-box001 {
  background-color: lightblue;
  display: none;
}
.tab_panel-box002 {
  background-color: lightcoral;
  display: none;
}
.tab_panel-box003 {
  background-color: lightgreen;
  display: none;
}
.tab_panel-box.is-show {
  display: block;
}

パネルを一旦非表示にしてから、is-showクラスを付けたパネルだけを表示することがポイントです。

次に、jsを作成します。

変数を新しく設定する際、都度console.log()でその変数を確認し、求める内容が求める数取得できているか、エラーがないかチェックします。最後にエラーが出てから問題の箇所を確定するには遡って細かくチェックする必要があるため、途中段階でコンソールで確認する方がベターです。

'use strict';

{
  // タブメニューアイテム全てのDOMを取得
  const tabMenus = document.querySelectorAll('.tab_menu-item');
  console.log(tabMenus);
  
  // 取得した各DOMにクリック時のイベントを追加
  tabMenus.forEach((tabMenu) => {
    tabMenu.addEventListener('click', tabSwitch);
  });

  function tabSwitch(e) {
    const tabTargetData = e.currentTarget.dataset.tab;
    console.log(e.currentTarget);
    console.log(e.currentTarget.dataset.tab);

    const tabList = e.currentTarget.closest('.tab_menu');
    console.log(tabList);
    const tabItems = tabList.querySelectorAll('.tab_menu-item');
    console.log(tabItems);

    const tabPanelItems = tabList.
    nextElementSibling.querySelectorAll('.tab_panel-box');
    console.log(tabPanelItems);

    //クリックしたタブの同階層のmenuとpanelのクラスを削除
    tabItems.forEach((tabItem) => {
      tabItem.classList.remove('is-active');
    })
    tabPanelItems.forEach((tabPanelItem) => {
      tabPanelItem.classList.remove('is-show');
    })

    //クリックされたmenu要素にis-activeクラスを付加
    e.currentTarget.classList.add('is-active');

    //クリックしたmenuのデータ属性と等しい値を持つパネルにis-showクラスを付加
    tabPanelItems.forEach((tabPanelItem) => {
      if(tabPanelItem.dataset.panel === tabTargetData) {
        tabPanelItem.classList.add('is-show');
      }
    })
  }
}

タブをクリックした際のクリックイベントで、そのタブ部分自体のクラスとそれに対応したタブのコンテンツのクラスを取得し、それを表示とするクラスを付加。

同じクリックイベントで、それ以外のタブのクラスとそのタブのコンテンツのクラスを取得し、表示するクラスを削除。

こうしてタブメニューの表示切替を行っています。

以下がサンプルです。

タブメニュー
  • menu1
  • menu2
  • menu3

初期表示のタブ内容 初期表示のタブ内容 初期表示のタブ内容 初期表示のタブ内容

2枚目のタブ内容 2枚目のタブ内容 2枚目のタブ内容 2枚目のタブ内容

3枚目のタブ内容 3枚目のタブ内容 3枚目のタブ内容 3枚目のタブ内容


コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です