【slick】独立したHTMLをスライダーの矢印ナビとして機能させる方法

【slick】独立したHTMLをスライダーの矢印ナビとして機能させる方法

ウェブサイトのビジュアルを向上させるために、スライダーは欠かせない要素です。しかし、スライダーのナビゲーションをカスタマイズし、独自のデザインや機能を持たせたい場合、標準のナビゲーションでは物足りないこともあります。この記事では、jQuerySlick Sliderを利用して、独立したHTMLをスライダーのナビとして機能させる方法を詳しく解説します。コピペで使えるコード例と共に、ステップバイステップで実装手順を紹介します。

基本設定

下記にてslickの基本を紹介していますのでご覧ください。

データURIの基本

データURIは、データを直接URL内に埋め込む方法で、通常は画像やフォントなどのリソースを外部ファイルとして読み込む代わりに、インラインで使用します。具体的には下記の記事をご覧ください

独立したHTMLナビのメリット

独立したHTMLナビを使用してslickスライダーのナビを実装する主なメリットは以下の通りです:

  • 自由な配置: ナビをスライダーの外部に配置することで、ページのレイアウトやデザインに合わせた柔軟な配置が可能です。
  • アクセシビリティの向上: カスタムボタンに適切なARIA属性を追加することで、スクリーンリーダーなどの支援技術への対応を強化できます。
  • 機能の拡張: カスタムボタンに追加の機能やアニメーションを組み込むことが容易になります。

CodePen ソースコードサンプル

HTML構造の設定

スライダーとナビゲーションのHTML構造を作成します。以下のコードを使用してください。

<div class="carousel">
  <ul class="carousel__nav">
    <li><a href="">スライド1</a></li>
    <li><a href="">スライド2</a></li>
    <li><a href="">スライド3</a></li>
    <li><a href="">スライド4</a></li>
    <li><a href="">スライド5</a></li>
  </ul>
  <div class="carousel__body slick">
    <div><img src="https://web-developer-note.com/codepen/images/slide01.jpg" alt="スライド1" width="600" height="400" class="imgauto"></div>
    <div><img src="https://web-developer-note.com/codepen/images/slide02.jpg" alt="スライド2" width="600" height="400" class="imgauto"></div>
    <div><img src="https://web-developer-note.com/codepen/images/slide03.jpg" alt="スライド3" width="600" height="400" class="imgauto"></div>
    <div><img src="https://web-developer-note.com/codepen/images/slide04.jpg" alt="スライド4" width="600" height="400" class="imgauto"></div>
    <div><img src="https://web-developer-note.com/codepen/images/slide05.jpg" alt="スライド5" width="600" height="400" class="imgauto"></div>
  </div>
</div>

ポイント:

  • .carouselクラス: スライダー全体を囲むコンテナ。
  • .carousel__navクラス: スライダーのナビゲーションリスト。各<li>要素には対応するスライドへのリンクが含まれます。
  • .carousel__bodyクラス: スライダー本体。slickクラスを追加することでSlick Sliderが適用されます。
  • 画像のalt属性: アクセシビリティ向上のため、各スライド画像に適切な代替テキストを設定します。

CSSスタイリング

スライダーとナビゲーションのスタイリングを行います。以下のCSSコードを使用してください。

.carousel{
  display: grid;
  grid-template-columns: repeat(2, 1fr);
}
.carousel__nav{
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.carousel__nav li{
  width: 80%;
}
.carousel__nav li:not(:last-child){
  border-bottom: 1px solid #ddd;
}
.carousel__nav li a{
  display: block;
  padding-block: 10px;
  position: relative;
  transition: .3s;
  text-decoration: none;
  color: #000;
}
.carousel__nav li.is-active a{
  transform: translateX(10px);
}
.carousel__nav li a::after{
  content: "";
  display: inline-block;
  --MASK: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMzAwIiB6b29tQW5kUGFuPSJtYWduaWZ5IiB2aWV3Qm94PSIwIDAgMjI0Ljg3OTk5IDIyNSIgaGVpZ2h0PSIzMDAiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIG1lZXQiIHZlcnNpb249IjEuMCIgc3R5bGU9ImJhY2tncm91bmQ6bm9uZTsiPjxkZWZzPjxjbGlwUGF0aCBpZD0iZWJhN2YwNjBkNSI+PHBhdGggZD0iTSAwIDAuMDU4NTkzOCBMIDIyNC43NjE3MTkgMC4wNTg1OTM4IEwgMjI0Ljc2MTcxOSAyMjQuOTM3NSBMIDAgMjI0LjkzNzUgWiBNIDAgMC4wNTg1OTM4ICIgY2xpcC1ydWxlPSJub256ZXJvIi8+PC9jbGlwUGF0aD48Y2xpcFBhdGggaWQ9Ijk5OWE2NGYwNGYiPjxwYXRoIGQ9Ik0gMzcuOTE0MDYyIDggTCAxNTggOCBMIDE1OCAyMTcgTCAzNy45MTQwNjIgMjE3IFogTSAzNy45MTQwNjIgOCAiIGNsaXAtcnVsZT0ibm9uemVybyIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNlYmE3ZjA2MGQ1KSI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTSAwIDAuMDU4NTkzOCBMIDIyNC44Nzg5MDYgMC4wNTg1OTM4IEwgMjI0Ljg3ODkwNiAyMjQuOTQxNDA2IEwgMCAyMjQuOTQxNDA2IFogTSAwIDAuMDU4NTkzOCAiIGZpbGwtb3BhY2l0eT0iMSIgZmlsbC1ydWxlPSJub256ZXJvIi8+PHBhdGggZmlsbD0ibm9uZSIgZD0iTSAwIDAuMDU4NTkzOCBMIDIyNC44Nzg5MDYgMC4wNTg1OTM4IEwgMjI0Ljg3ODkwNiAyMjQuOTQxNDA2IEwgMCAyMjQuOTQxNDA2IFogTSAwIDAuMDU4NTkzOCAiIGZpbGwtb3BhY2l0eT0iMSIgZmlsbC1ydWxlPSJub256ZXJvIi8+PC9nPjxnIGNsaXAtcGF0aD0idXJsKCM5OTlhNjRmMDRmKSI+PHBhdGggZmlsbD0iIzAwMDAwMCIgZD0iTSA0Mi4yOTY4NzUgMTAxLjkyMTg3NSBDIDM2LjQ2ODc1IDEwNy43NDIxODggMzYuNDY4NzUgMTE3LjE5MTQwNiA0Mi4yOTY4NzUgMTIzLjAxMTcxOSBMIDEzMS44MDA3ODEgMjEyLjM5ODQzOCBDIDEzNy42MjUgMjE4LjIxNDg0NCAxNDcuMDg5ODQ0IDIxOC4yMTQ4NDQgMTUyLjkxNzk2OSAyMTIuMzk4NDM4IEMgMTU4Ljc0MjE4OCAyMDYuNTc4MTI1IDE1OC43NDIxODggMTk3LjEyNSAxNTIuOTE3OTY5IDE5MS4zMDg1OTQgTCA3My45NDkyMTkgMTEyLjQ0NTMxMiBMIDE1Mi44NzEwOTQgMzMuNTc4MTI1IEMgMTU4LjY5NTMxMiAyNy43NjE3MTkgMTU4LjY5NTMxMiAxOC4zMDg1OTQgMTUyLjg3MTA5NCAxMi40ODgyODEgQyAxNDcuMDQyOTY5IDYuNjcxODc1IDEzNy41NzgxMjUgNi42NzE4NzUgMTMxLjc1MzkwNiAxMi40ODgyODEgTCA0Mi4yNSAxMDEuODc1IFogTSA0Mi4yOTY4NzUgMTAxLjkyMTg3NSAiIGZpbGwtb3BhY2l0eT0iMSIgZmlsbC1ydWxlPSJub256ZXJvIi8+PC9nPjwvc3ZnPg==) no-repeat center center / 100%;
  mask: var(--MASK);
  -webkit-mask: var(--MASK);
  background-color: #000;
  aspect-ratio: 1/1;
  width: 15px;
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%) rotate(180deg);
  opacity: 0;
  transition: .3s;
}
.carousel__nav li.is-active a::after{
  opacity: 1;
}

例としてデータURI化した元画像を添付します

JavaScriptによるスライダー設定

Slick Sliderを初期化し、ナビゲーションとの連携を設定します。以下のJavaScriptコードを使用してください。

$(document).ready(function(){
  var sliderClass = '.carousel__body';
  var navItemClass = '.carousel__nav li';
  var activeClass = 'is-active';

  // Slick Sliderの初期化
  $(sliderClass).slick({
    dots: false,
    arrows: false,
    autoplay: true,
    autoplaySpeed: 3000,
    fade: true,
    speed: 800,
    pauseOnFocus: false,
    pauseOnHover: false,
    pauseOnDotsHover: false,
    waitForAnimate: false,
    responsive: [
      {
        breakpoint: 767,
        settings: {
          dots: false,
        }
      }
    ]
  });

  // ホバーイベントの設定
  function setHoverEvents() {
    $(navItemClass).on('mouseenter', function () {
      var slideIndex = $(this).index();
      $(sliderClass).slick('slickGoTo', slideIndex);
    });

    $(navItemClass).on('mouseleave', function () {
      $(navItemClass).removeClass(activeClass);
    });
  }

  // クリックイベントの設定
  function setClickEvents() {
    $(navItemClass).on('click', function () {
      var slideIndex = $(this).index();
      $(sliderClass).slick('slickGoTo', slideIndex);
    });
  }

  // スライダーが変更される前にナビゲーションを更新
  $(sliderClass).on('beforeChange', function (event, slick, currentSlide, nextSlide) {
    $(navItemClass).removeClass(activeClass);
    $(navItemClass).eq(nextSlide).addClass(activeClass);
  });

  // 最初のナビゲーションアイテムをアクティブに設定
  $(navItemClass).eq(0).addClass(activeClass);

  // ウィンドウ幅に応じてイベントを設定
  function updateEventsBasedOnWidth() {
    $(navItemClass).off('mouseenter mouseleave click');

    if (window.innerWidth >= 768) {
      setHoverEvents();
    } else {
      setClickEvents();
    }
  }

  // 初期設定
  updateEventsBasedOnWidth();

  // ウィンドウサイズ変更時にイベントを更新
  $(window).on('resize load', function () {
    updateEventsBasedOnWidth();
  });
});

詳細解説:

  • 変数の設定:
    • sliderClass: スライダー本体のクラス(.carousel__body)。
    • navItemClass: ナビゲーションリストの各アイテム(.carousel__nav li)。
    • activeClass: アクティブなナビゲーションアイテムに付与するクラス名(is-active)。
  • イベント設定関数:
    • setHoverEvents(): マウスホバー時に対応するスライドに移動するイベントを設定。
    • setClickEvents(): クリック時に対応するスライドに移動するイベントを設定。
  • スライダーの変更イベント:
    • beforeChange: スライダーがスライドを変更する前に、現在のアクティブクラスを削除し、次のスライドに対応するナビゲーションアイテムにis-activeクラスを追加。
  • 初期アクティブ設定:
    • 最初のナビゲーションアイテムにis-activeクラスを追加。
  • レスポンシブ対応:
    • ウィンドウ幅に応じて、ホバーイベントまたはクリックイベントを適用。幅が768px以上の場合はホバー、以下の場合はクリックでスライドを変更。
    • ウィンドウのリサイズやロード時にイベントを再設定。

ナビゲーションの動作説明

この実装では、独立したHTMLリストをスライダーのナビゲーションとして機能させています。以下に、その動作を詳しく説明します。

スライダーが自動的にスライドを切り替える際に、ナビゲーションアイテムのis-activeクラスが更新され、現在表示されているスライドに対応するナビゲーションアイテムが強調表示されます。

ホバー時の動作(デスクトップ環境):

ユーザーがナビゲーションリストのアイテムにマウスホバーすると、対応するスライドに移動します。

ホバーしたアイテムにはis-activeクラスが付与され、視覚的なフィードバック(例えば、横方向への移動)が適用されます。

クリック時の動作(モバイル環境):

モバイルデバイスでは、ホバー操作が難しいため、ユーザーがナビゲーションアイテムをクリックすると、対応するスライドに移動します。

クリックされたアイテムにis-activeクラスが付与され、選択状態が示されます。

スライダーの自動再生との連携:

スライダーが自動的にスライドを切り替える際に、ナビゲーションアイテムのis-activeクラスが更新され、現在表示されているスライドに対応するナビゲーションアイテムが強調表示されます。

まとめ

この記事では、jQuerySlick Sliderを利用して、独立したHTMLをスライダーのナビゲーションとして機能させる方法を紹介しました。以下に主なポイントをまとめます。

主なポイント:

  • 独立したナビゲーションHTML: ナビゲーションリストを独立したHTML構造として作成し、スライダーと連携させることで、柔軟なデザインと操作性を実現。
  • Slick Sliderの活用: Slick Sliderを使用することで、レスポンシブでカスタマイズ可能なスライダーを簡単に実装。
  • jQueryによるイベント管理: ホバーとクリックイベントを適切に設定し、デバイスに応じたユーザー体験を提供。
  • レスポンシブデザイン: メディアクエリとJavaScriptの条件分岐を活用し、デスクトップとモバイルで最適な操作性を確保。
この記事をシェアする

どなたでもコメントや質問をどうぞ

スパム対策のため、承認作業を行うまでは表示されません。ご了承ください。

CAPTCHA