LoginSignup
2
2

More than 3 years have passed since last update.

タブ切り替えのjsについて(3パターン)

Last updated at Posted at 2020-05-10

js 動作のタブ制作を調べていると、簡単に作れるものとして下記がよく見つかるような気がする。

下記では、jQueryを使って、ボックスエリアをタブと同じ順に並べた形で、表示・非表示を行う形式。

■1つ目

<ul class="l-tab-btns">
  <li class="tab1"><button class="js-button is-active">ボタン1</button></li>
  <li class="tab2"><button class="js-button">ボタン2</button></li>
</ul>
<div id="tab1" class="tab-box">
  タブ1の中身(ボックスエリア1)
</div>
<div id="tab1" class="tab-box is-hidden">
  タブ2の中身(ボックスエリア2)
</div>
$(function () {
  $('.js-button').on('click', function () {

    //クリックしたタブのインデックス順を取得
    var index = $('.js-button').index(this);

    //タブ全てからアクティブクラスを排除。
    $('.js-button').removeClass('is-active');

    //クリックしたタブをアクティブに。
    $(this).addClass('is-active');

    //全てのタブエリアに非表示クラスを追加し、クリックしたタブと同じ順のタブエリアから非表示クラスを削除
    $('.tab-box').addClass('is-hidden').eq(index).removeClass('is-hidden');
    return false;
  });
});

クリックしたタブが何番目のタブなのかを数え、それと同じ順序に並んでいるボックスエリアのソースを表示させるというもの。

ただこの方法だと、タブの順とボックスエリアの順はそろえて置く必要がある。

■2つ目

そこで下記では、タブの順に、ボックスエリアをの順を合わせる必要が無い形をとった。

ボックスエリアに各idを設置し、タブボタンのhrefに開きたいタブを指定してある。

<div class="m-tab">
  <ul class="m-tab-btnList">
    <li class="m-tab-btn is-active"><a href="#tab1">ボタン1</a></li>
    <li class="m-tab-btn"><a href="#tab2">ボタン2</a></li>
  </ul>
  <div class="m-tab-box is-tab-open" id="tab1">
    タブ1の中身(ボックスエリア1)
  </div>
  <div class="m-tab-box" id="tab2">
    タブ2の中身(ボックスエリア2)
  </div>
</div>
$(function () {
  $('.js-tab a').on('click', function () {

    //クリック自身にはクラス付加し、対象から親に上ってその兄弟にはクラス削除。
    $(this).parent().addClass('is-active').siblings('.is-active').removeClass('is-active');

    // クリックしたものからhref取得
    var id = $(this).attr('href');

    //対象クラスを全て破棄。
    $('.js-tab-box').siblings('.is-tab-open').removeClass('is-tab-open');

    //指定のクラスにクラス追加
    $(id).addClass('is-tab-open');
    return false;
  });
});

■3つ目

また下記では、勉強のために内部処理をjQueryを禁止して、javascriptだけで記載してみた。

htmlでは、data属性に開きたいタブのidを記載し連携してある。

<ul class="m-tab-lists">
  <li class="m-tab-list is-active"><button class="js-tab-btn" data-tab="tab1">ボタン1</button></li>
  <li class="m-tab-list"><button class="js-tab-btn" data-tab="tab2">ボタン2</button></li>
</ul>
<div class="m-tab-box js-tab-box is-open" id="tab1">
  タブ1の中身(ボックスエリア1)
</div>
<div class="m-tab-box js-tab-box" id="tab2">
  タブ2の中身(ボックスエリア2)
</div>
$(function () {
  //-- タブ切り替え --------------------------------------------------------------------
  // 対象クラスのついているDOM全てを取得
  var btn = document.getElementsByClassName('js-tab-btn');

  // btn.length で 対象ボタンの個数全部を取得し、条件式が0になるまで回す。
  // 要素indexは0から割り振られているので-1することで、個数を、indexに合わせる。
  for (var i = btn.length - 1; i >= 0; i--) {
    // 各ボタン、イベントリスナーでクリックしたら発動
    btn[i].addEventListener('click', function () {

      // btn.length で 対象ボタンの個数全部を取得し、条件式が0になるまで回す。
      for (var x = btn.length - 1; x >= 0; x--) {
        // contains で対象クラス有無をチェックし、あれば削除
        if (btn[x].parentNode.classList.contains('is-active')) {
          btn[x].parentNode.classList.remove('is-active');
        }
      }

      // this はクリックされたオブジェクト。parentNode でその親。
      // classList でクラス操作。is-active クラスの追加と削除。
      this.parentNode.classList.add('is-active');

      // 対象クラスのついているDOM全てを取得
      var box = document.getElementsByClassName('js-tab-box');
      for (var y = box.length - 1; y >= 0; y--) {
        // contains で対象クラス有無をチェックし、あれば削除
        if (box[y].classList.contains('is-open')) {
          box[y].classList.remove('is-open');
        }
      }

      //data属性の値を取得して、同じidの要素にクラス付加。
      var tab_id = this.getAttribute('data-tab');
      document.getElementById(tab_id).classList.add('is-open');
    });
  }
});

上記のようにjavascriptでも対応できるが、jQueryで済むならそれに越したことはない。

■参照

以下は参照。

https://blog-and-destroy.com/7389
https://www.flatflag.nir87.com/tab-1960

https://www.mdn.co.jp/di/contents/4047/54019/
https://www.mdn.co.jp/di/contents/4047/54084/

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2