‍🦔 jsでモジュール化(タブ切り替え)
作成日: 2024/01/26
0

今回はコンポーネント化させて、処理を一つ一つのファイルで管理する方法

main.js

//----------------------------------------------------------------------
//  import
//----------------------------------------------------------------------
import { tab } from "./sub.js";
tab();

呼び出し側は`import {呼び出したい関数名} from "ファイルの場所&名前"
関数名();で実行する

sub.js

export function tab() {
//中身の処理
};

呼ばれる側はexport function 関数名とする
今回は引数でタブのクラス名を取りたいので上記の書き方にした。

完成形(タブ)

<div class="tab-wrapper">
      <div class="tab"><input class="tab-input" id="tab-a" type="radio" name="tab-radio" value="usage" checked="" />
        <h2 class="tab-label-heading selected"><label class="tab-label" for="tab-a">タブA</label></h2>
      </div>
      <div class="tab"><input class="tab-input" id="tab-b" type="radio" name="tab-radio" value="type" />
        <h2 class="tab-label-heading"><label class="tab-label" for="tab-b">タブB</label></h2>
      </div>
      <div class="tab"><input class="tab-input" id="tab-c" type="radio" name="tab-radio" value="maker" />
        <h2 class="tab-label-heading"><label class="tab-label" for="tab-c">タブC</label></h2>
      </div>
    </div>
    <div class="tab-panel panel-a">
      <div>
        <p>タブAの中身</p>
      </div>
    </div>
    <div class="tab-panel panel-b">
      <div>
        <p>タブBの中身</p>
      </div>
    </div>
    <div class="tab-panel panel-c">
      <div>
        <p>タブCの中身</p>
      </div>
</div>

<style>
/************************
//         tab         //
************************/
.tab-wrapper{
	display: flex;
    column-gap: 2px;
	input[type="radio"] {
      display: none;
	}
	.selected > .tab-label{
      color: #000;
      background-color: #e2e8eb;
      transition: .3s;
	}
    .tab-label {
      display: block;
      background-color: #b4bdbf;
      color: #525252;
      cursor: pointer;
      font-size: 16px;
      padding: 10px 20px;
      transition: .3s;
      &:hover {
        opacity: .7;
      }
	}
}
  .tab-panel{
    background-color: #e2e8eb;
    height: 170px;
    &>div {
      display: flex;
      height: 100%;
      align-items: center;
      justify-content: center;
    }
  }
  .panel-b,
  .panel-c{
    display: none;
  }
</style>
<script>
//main.js
//----------------------------------------------------------------------
//  import
//----------------------------------------------------------------------
import { tab } from "./sub.js";
tab('.panel-a', '.panel-b', '.panel-c');

//sub.js
export function tab(tab01, tab02, tab03) {
  const tab_elements = document.getElementsByName('tab-radio');
  const tab_panel_a = document.querySelector(tab01);
  const tab_panel_b = document.querySelector(tab02);
  const tab_panel_c = document.querySelector(tab03);

  tab_elements.forEach( function(tab_element) {
    tab_element.addEventListener('click', function(){
       if (tab_element.id == 'tab-a'){
          tab_panel_a.style.display = 'block';
          tab_panel_b.style.display = 'none';
          tab_panel_c.style.display = 'none';
       }else if (tab_element.id == 'tab-b'){
          tab_panel_a.style.display = 'none';
          tab_panel_b.style.display = 'block';
          tab_panel_c.style.display = 'none';
       }else if (tab_element.id == 'tab-c'){
          tab_panel_a.style.display = 'none';
          tab_panel_b.style.display = 'none';
          tab_panel_c.style.display = 'block';
       }
       // 選択されたかどうかを示すクラス名「selected」の付与と削除
       tab_elements.forEach( function(tab_element) {
          tab_element.nextElementSibling.classList.remove('selected');
       });
       tab_element.nextElementSibling.classList.add('selected');
    });
 });
};
</script>

感想

コンポーネント化できる事で他への影響を与えずに修正できるし呼び出し側で関数の引数にクラス名を入れるだけでそれぞれで使い回しができる


フロントエンドエンジニアを頑張って勉強中。 最近はVueやNuxtを勉強中です。 コミュニティなどあれば参加してみたいと思ってます。 どうぞ、生暖かい目で見ていただけると幸いです。