jQueryを使って中身がふわっと表示されるタブ切り替えを実装してみる(パターン3)(備忘録)

今回は、jQueryを使用して中身がふわっと表示されるタブ切り替えを実装してみることにした。

前回のページと挙動はほとんど同じである。アプローチが異なるので紹介していきたいと思う。

下記にデモは作ったのでご覧いただければと思う。

では実装に入っていきたいと思う。

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="../reset.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main>
    <section>
      <div class="ly_inner" id="menu1">
        <h2>menu1</h2>
        <!-- タブ切り替え -->
        <div class="bl_tabContainer">
          <ul class="bl_tabList">
            <li><a href="" class="active">Tab01</a></li>
            <li><a href="">Tab02</a></li>
            <li><a href="">Tab03</a></li>
          </ul>
          <div class="bl_tabContent">
            <!-- Tab01の内容 -->
            <div class="active">
              <p>Tab01の内容が入りますTab01の内容が入りますTab01の内容が入りますTab01の内容が入りますTab01の内容が入りますTab01の内容が入りますTab01の内容が入りますTab01の内容が入りますTab01の内容が入りますTab01の内容が入ります</p>
            </div>
            <!-- //Tab01の内容 -->
            <!-- Tab02の内容 -->
            <div>
              <p>Tab02の内容が入ります</p>
              <p>Tab02の内容が入ります</p>
              <p>Tab02の内容が入ります</p>
              <p>Tab02の内容が入ります</p>
              <p>Tab02の内容が入ります</p>
              <p>Tab02の内容が入ります</p>
              <p>Tab02の内容が入ります</p>
              <p>Tab02の内容が入ります</p>
            </div>
            <!-- //Tab02の内容 -->
            <!-- Tab03の内容 -->
            <div>
              <p>Tab03の内容が入ります</p>
            </div>
            <!-- //Tab03の内容 -->
          </div>
        </div>
        <!-- //タブ切り替え -->
        <div class="md_textblock">
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
        </div>
      </div>
    </section>

  </main>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  <script src="style.js"></script>
</body>
</html>

htmlのソースは下記の記事と同じだ。

javascriptのfor文で中身がふわっと表示されるタブ切り替えを実装してみる(パターン1)(備忘録)

cssの記述について

@charset "utf-8";

/* ==========================
  初期設定
========================== */
*,
*::before,
*::after {
  box-sizing: border-box;
}
img {
  width: 100%;
}

/* ==========================
  タブ
========================== */

.bl_tabContainer + * {
  margin-top: 30px;
}
/* タブリスト */
.bl_tabList {
  display: flex;
  justify-content: space-between;
}
.bl_tabList li {
  width: 32%;
}
.bl_tabList li a {
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #aaa;
  padding: 20px 10px;
  transition: 0.3s;
}
.bl_tabList li a.active {
  background-color: #fff;
  cursor: text;
}
/* タブコンテンツ */
.bl_tabContent > div {
  background-color: #fff;
  padding: 20px;
  display: none;
}
.bl_tabContent > div.active {
  display: block;
}
.bl_tabContent > div > * + * {
  margin-top: 10px;
}

/* ==========================
  タブ以外のコンテンツの中身
========================== */
.ly_inner {
  width: 100%;
  max-width: 1080px;
  margin: 100px auto;
  padding: 30px;
  background-color: #ccc;
}
.ly_inner h2 {
  font-size: 150%;
  font-weight: bold;
  margin-bottom: 30px;
}
.md_textblock > * + * {
  margin-top: 10px;
}

/* ====================================
  ここからPC幅
==================================== */
@media screen and (min-width: 768px) {
  .hp_displaySP {
    display: none !important;
  }

  .bl_tabList li a:not(.active):hover {
    background-color: #fff;
  }
}

/* ====================================
  ここからスマホ幅
==================================== */
@media screen and (max-width: 767px) {
  .hp_displayPC {
    display: none !important;
  }
}

こちらは前回の記事では、opacityやpositionなどを使って表示非表示の対応をとっていたが、今回はjQueryでfadeを使って制御する関係で下記のソースに変更している。

/* タブコンテンツ */
.bl_tabContent > div {
  background-color: #fff;
  padding: 20px;
  display: none;
}
.bl_tabContent > div.active {
  display: block;
}

ページを読み込んだときに、タブコンテンツにactiveがついていないクラスの中身はdisplay: none;で表示されないようにし、activeがついているクラスはdisplay: block;で中身が表示されるようにしている。

javascriptの記述について

'use strict';

// タブ切り替え
$(function(){
  $('.bl_tabList li a').click(function (e) {
    e.preventDefault();
    $('.bl_tabList li a').removeClass('active');
    $('.bl_tabContent > div').removeClass('active');
    $(this).addClass('active');
    const array = $('.bl_tabList li a').index(this);
    $('.bl_tabContent > div').eq(array).fadeIn(300).addClass('active');
    $('.bl_tabContent > div').not('.active').hide();
  });
});

// スムーススクロール
window.addEventListener('DOMContentLoaded', function () {
  const anchorLinks = document.querySelectorAll('a[href^="#"]');
  const anchorLinksArr = Array.prototype.slice.call(anchorLinks);

  anchorLinksArr.forEach(function (link) {
    link.addEventListener('click', function (e) {
      e.preventDefault();
      const targetId = link.hash;
      const targetElement = document.querySelector(targetId);
      const targetOffsetTop = window.pageYOffset + targetElement.getBoundingClientRect().top; //ここに- 50 などと数値を入れるとヘッダー固定のスクロールが実現できる
      window.scrollTo({
        top: targetOffsetTop,
        behavior: "smooth"
      });
    });
  });
});

前回と少し似ているが、aリンクはページが遷移しないようにpreventDefaultを設定している。

まず、タブをクリックした時に全てのタブ(.bl_tabList li a)に対してremoveClassを設定することによりactiveのクラスが外れるように設定する。

また同時に、タブコンテンツ全て(.bl_tabContent > div)に対してremoveClassを設定することによりactiveのクラスが外れるよう設定する。

その後、クリックしたタブ(this)にactiveのクラスが付与される。このthisというのは何を指しているのかというと、「クリックした時の.bl_tabList li a」である。「全ての.bl_tabList li a」を指しているわけではないため注意したいところだ。

続いて、クリックされたタブと同じ順番のタブコンテンツに対してactiveのクラスを付与したいのだが、変数をおいてあげる必要がある。

変数の名前はarrayとしているが、任意の名前で大丈夫だ。何番目の要素に当たるのかを取得するために、$(‘.bl_tabList li a’).index(this)を入れている。

indexは引数で指定されたエレメントのインデックス番号を返し、html上の1番目、2番目を、jQueryでは0番目(html上の1番目)、1番目(html上の1番目)と数えていく。

これでタブをクリックした時に、何番目がクリックされているのかがarrayの変数で取得できるようになる。

この変数arrayを利用して、タブコンテンツに対して、fadeInでふわっと表示されるようactiveのクラスをつけていく。

$('.bl_tabContent > div').eq(array).fadeIn(300).addClass('active');

eqについて

eqというのは、htmlの要素の集合から、指定したポジションの要素だけを取り出す。

例えば、html要素の中にliタグが4つあるとした場合、3番目を取り出したいときなどにeq(2)と指定することで3番目の要素を取り出すことができる。eqを2と指定したのは、javascriptでは配列の数え方が0から始まるからである。

ここで上記のeq(array)について考えていくと、これは何番目のタブをクリックしているのかを取り出している事になる。クリックする度にその取得される番号は変わっていくようになっている。

fadeInについて

fadeInは、jQuey上でhtml要素をふわっと表示させたいような時に使用する。

まずポイントとしては、css側でふわっと表示させたい要素に対して「display: none;」が設定されてるかだ。

fadeInは実行されると、要素に対して「display: block;」が付与されるので、そのために実行される前の要素に対して「display: none;」を設定している。

また、要素が実行されて別のタブをクリックした時でも、以前にクリックしていたところが実行されたままの状態になってしまうため、その状態を解除しなくてはならない。この対応については後述したいと思う。

fadeIn()の括弧の中には、数字を入れると秒数の指定、slow、normal、fastを入れたりして表示速度をコントロールすることができる。

今回はfadeIn(300)と指定して、0.3秒でタブコンテンツが表示されるようにした。

$('.bl_tabContent > div').not('.active').hide();

続いて、activeのクラスが付与されていないタブコンテンツが表示されないように設定する指定だ。

先ほど記載したが、fadeIn()を実行した時に、他のタブをクリックして2回目のfadeIn()が実行された時に、1回目に実行されていたものがdisplay: block;で残った状態になっている。

これを非表示にするために、activeがついていないクラスに対してhide()を使用して非表示にしていく。hideが実行されると該当のhtml要素にdisplay: none;が付与される。

以上で終わりだが、fadeInやhide以外にもfadeOutやshowなど色々なメソッドがあるので調べてカスタマイズしてみると面白いかもしれない。

スムーススクロールの記述は組み合わせて使うことが多いので、前回同様残している。解説は省略したいと思う。

次回もタブ切り替えシリーズの別パターン実装をやっていきたいと思う。

1 返信

トラックバック & ピングバック

コメントはクローズされています。