今回の記事は、「jQueryでスライダー作成その② 」の続きです。
前回作成したスライダーに新しく機能を追加してみました。
追加した機能
追加した機能は以下の通りです。
- マウスの動きに合わせて、ボタンの表示・非表示を切り替え
 - 画像が何枚目なのか視覚的にわかりやすいナビを追加(インジケータ)
 
早速作っていきます!
完成コード
タブメニューになっているので切り替えると、HTML・CSS・jQueryのコードが表示されます。
完成コードはこちらです↓
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <title>
      コンテンツスライダー③
    </title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <div class="l-container" id="js-sliderContent">
      <h1 class="m-pageTitle">
        コンテンツスライダー③<br />
        <span>
          不具合により自動再生されない場合があります。<br />
          その場合、ブラウザを何度かリロードお願いいたします。
        </span>
      </h1>
      <div class="m-sliderArea">
        <div class="m-sliderWrap">
          <ul class="js-slider m-slider">
            <li class="js-sliderItem m-slider__item">
              <img src="images/grape.jpg" alt="ぶどう" />
            </li>
            <li class="js-sliderItem m-slider__item">
              <img src="images/apple.jpg" alt="りんご" />
            </li>
            <li class="js-sliderItem m-slider__item">
              <img src="images/lemon.jpg" alt="レモン" />
            </li>
            <li class="js-sliderItem m-slider__item">
              <img src="images/pineapple.jpg" alt="パイナップル" />
            </li>
            <li class="js-sliderItem m-slider__item">
              <img src="images/strawberry.jpg" alt="いちご" />
            </li>
          </ul>
        </div>
        <!-- /.m-sliderWrap -->
        <ul class="m-sliderNav" id="js-sliderNav">
          <li class="m-sliderNav__item">
            <button class="m-button --slider --prev" id="js-sliderPrevButton">
              <span class="u-visuallyHidden">前へ</span>
            </button>
          </li>
          <li class="m-sliderNav__item">
            <button class="m-button --slider --next" id="js-sliderNextButton">
              <span class="u-visuallyHidden">次へ</span>
            </button>
          </li>
        </ul>
      </div>
      <!-- /.m-sliderArea -->
    </div>
    <!-- /.l-container -->
    <script
      src="https://code.jquery.com/jquery-1.12.4.min.js"
      integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="
      crossorigin="anonymous"
    ></script>
    <script src="app.js"></script>
  </body>
</html>
CodeSandBox で簡単なデモページを作成しました!
※1レスポンシブには対応していないので、恐れ入りますがPCからご覧ください。
※2不具合で自動再生が機能しない可能性があります。その場合、ブラウザを何度かリロードお願いいたします。
ボタンのデザイン変更
HTMLの構造変更
まず、ボタンのデザインを変更します。
変更点はこちら↓
・ボタンを囲ってるul要素にid属性js-sliderNavを追加。
・m-sliderWrapとm-sliderNavをclass属性m-sliderAreaを持つdiv要素で囲む。
・button要素にclass属性—sliderを付ける。
・button要素内のコンテンツをclass属性u-visuallyHiddenを持つspan要素で囲み、
CSSで見た目上、見えないよう装飾する。
<div class="m-sliderArea">
	<div class="m-sliderWrap">
	  <ul class="m-slider" id="js-slider">
	    <li class="js-sliderItem m-slider__item">
	      <img src="images/photo-mountain.jpg" alt="ぶどう" />
       </li>
       <li class="js-sliderItem m-slider__item">
         <img src="images/photo-river.jpg" alt="りんご" />
	     </li>
       <li class="js-sliderItem m-slider__item">
         <img src="images/photo-sea.jpg" alt="レモン" />
       </li>
       <li class="js-sliderItem m-slider__item">
         <img src="images/photo-town.jpg" alt="パイナップル" />
       </li>
       <li class="js-sliderItem m-slider__item">
          <img src="images/photo-sky.jpg" alt="いちご" />
        </li>
      </ul>
    </div>
    <!-- /.m-sliderWrap -->
    <ul class="m-sliderNav" id="js-sliderNav">
	    <li class="m-sliderNav__item">
	      <button class="m-button --slider --prev" id="js-sliderPrevButton">
	        <span class="u-visuallyHidden">前へ</span>
        </button>
      </li>
      <li class="m-sliderNav__item">
        <button class="m-button --slider --next" id="js-sliderNextButton">
		      <span class="u-visuallyHidden">次へ</span>
        </button>
        </li>
     </ul>
</div>
<!-- /.m-sliderWrap -->ボタンを装飾
ボタンを円形にし、button要素内のコンテンツを矢印に変更します。
ボタンの位置は、画像の上下中央を基準に、
「前へ」ボタンは画像の左側に、「次へ」ボタンは画像の右側に配置させます。
.m-sliderArea {
    position: relative;
    padding: .5em;
    background-color: #333;
}
.m-button.--slider {
    position: absolute;
    inset: 0 auto 0 auto;
    width: 5em;
    height: 5em;
    margin: auto 0;
    border: none;
    border-radius: 50%;
    box-shadow: 0 0 10px #333;
    font-size: 16px;
    cursor: pointer;
}
.m-button.--slider:active {
    box-shadow: none;
}
.m-button.--slider::before {
    content: "";
    position: absolute;
    inset: 0;
    margin: auto;
    width: 1em;
    height: 1em;
    border: 2px solid #333;
    transform: rotate(45deg);
}
.m-button.--prev {
    left: -2.5em;
}
.m-button.--prev::before {
    left: .5em;
    border-top: none;
    border-right:none ;
}
.m-button.--next {
    right: -2.5em;
}
.m-button.--next::before {
    right: .5em;
    border-bottom: none;
    border-left:none ;
}ボタンの表示・表示切り替え
マウスの動きに合わせて、ボタンの表示・非表示を切り替えます。
切り替えるスピードは変数で管理します。
切り替えるときの条件がこちら↓
・コンテンツの上にマウスが乗ったら、ボタンを非表示
・コンテンツの上からマウスが離れたら、ボタンを表示
//ボタンの表示・非表示切り替え時間
var buttonFadeSpeed = 300;
//マウスの動きに合わせた処理
$(".js-sliderItem").hover(
	function () {
     //マウスが乗っている時
	   //ボタンを非表示
     $("#js-sliderNav").fadeOut(buttonFadeSpeed);
     
      clearInterval(slideTimer);
	   }, 
	function () {
      //マウスが離れた時
      //ボタンを表示
      $("#js-sliderNav").fadeIn(buttonFadeSpeed);
      slideSetTimer();
     }
);インジケータ機能を追加
現在表示している画像が何枚目なのか、分かりやすいナビ機能を追加します。
インジケータに必要な要素をJSで追加
コンテンツの数が増減するとそれに合わして、インジケータも増減できるようにJavaScriptで
必要な要素を追加します。
追加するときの要件は以下の通りです↓
・l-containerにid属性js-sliderContentを追加する。
・js-sliderContentの末尾にclass属性m-indicator、
id属性js-indicatorを持つul要素を追加する。
・for文を使ってコンテンツの数だけul要素内にli>button>spanを追加する。
・button要素にカスタムデータ属性を追加する。
<div class="l-container" id="js-sliderContent">
	<!--中身省略-->     
</div>
<!-- /.l-container -->自動再生と対応してインジケータボタンにclass属性を追加
まず、data-id属性が0のインジケータボタンにclass属性is-sliderActiveを付けます。
次に、自動再生の関数内の先頭で、
一度インジケータボタンについているclass属性を削除します。
そして、関数内の末尾で、表示中の画像と対応しているインジケータボタンに、
class属性を追加します。
また、CSSでインジケータボタンのレイアウトと、class属性が付いているインジケータボタンを目立たせます。
.m-indicator {
    display: flex;
    justify-content: center;
    padding-top: 2em;
}
.m-indicator__item+.m-indicator__item {
    margin-left: 1em;
}
.m-button.--indicator {
    font-size: 16px;
    width: 1.5em;
    height: 1.5em;
    border: none;
    border-radius: 50%;
    box-shadow: 0 0 5px #000;
}
.m-button.--indicator:active {
    box-shadow: none;
}
.m-button.is-sliderActive {
    position: relative;
}
.m-button.is-sliderActive::before {
    content: "";
    position: absolute;
    inset: 0;
    margin: auto;
    width: 1em;
    height: 1em;
    border-radius: 50%;
    background-color: #000;
}インジケータボタンのクリックイベント
インジケータボタンのクリックイベントを作成します。
クリックイベント内の処理の流れは以下の通りです。
1.自動再生停止
2.クリックしたインジケータボタンのdata-id属性の値を取得
3.コンテンツ番号を取得したdata-id属性の値に変更
4.sliding()を呼び出す
5.自動再生を再開
// インジケータボタンを押した時の処理
$(".js-indicatorButton").click(function () {
    clearInterval(slideTimer);
    //クリックしたインジケータボタンのdata-id属性を変数で管理
    var indicatorId = $(this).attr("data-id");
    //コンテンツ番号をindicatorIdの値に置き換え
    index = indicatorId;
    sliding();
    slideSetTimer();
 });まとめ
以上でボタンの表示・非表示切り替えとインジケータ機能の追加ができました。
最後まで読んでいただきありがとうございました!
