
目次
ウェブサイトのビジュアルを向上させるために、スライダーは欠かせない要素です。しかし、スライダーのナビゲーションをカスタマイズし、独自のデザインや機能を持たせたい場合、標準のナビゲーションでは物足りないこともあります。この記事では、jQueryとSlick 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クラスが更新され、現在表示されているスライドに対応するナビゲーションアイテムが強調表示されます。
まとめ
この記事では、jQueryとSlick Sliderを利用して、独立したHTMLをスライダーのナビゲーションとして機能させる方法を紹介しました。以下に主なポイントをまとめます。
主なポイント:
- 独立したナビゲーションHTML: ナビゲーションリストを独立したHTML構造として作成し、スライダーと連携させることで、柔軟なデザインと操作性を実現。
- Slick Sliderの活用: Slick Sliderを使用することで、レスポンシブでカスタマイズ可能なスライダーを簡単に実装。
- jQueryによるイベント管理: ホバーとクリックイベントを適切に設定し、デバイスに応じたユーザー体験を提供。
- レスポンシブデザイン: メディアクエリとJavaScriptの条件分岐を活用し、デスクトップとモバイルで最適な操作性を確保。