プラグイン使用せずに汎用性の高いコンテンツスライダー作成しました[jQuery 編]。
2020.05.16
みなさま、こんにちは。
先日、プラグインを使用せずにスライダーを作成してほしいという依頼がありましたので、頑張ってみました。
いつもはプラグイン「slick」を使用しているので、簡単にスライダーを実装していたのですが、がっつり組むとなると意外と複雑で、勉強になりました。
プラグインはオプションありきで、カスタマイズ性が低いので、自作するのもいいかもしれません。
自分で仕様がわかっている分、カスタマイズもしやすいので。
プラグイン使わずにスライダーを設計してみた。
それではコードを載せていきますので、参考にしてみてください。
ふわっと、フィードで変化するスライダー
まずはDEMOを参照してみてください。
5秒ごとに変化するので、慌てず見守ってください。
1 2 3 4 5 6 7 8 |
<div class="js-slider"> <ul class="slider_list"> <li class="slider_list_item"><img src="https://placehold.jp/fffd34/ffffff/768x432.png?text=number_01" alt="number_01"></li> <li class="slider_list_item"><img src="https://placehold.jp/fe5409/ffffff/768x432.png?text=number_02" alt="number_02"></li> <li class="slider_list_item"><img src="https://placehold.jp/8701b0/ffffff/768x432.png?text=number_03" alt="number_03"></li> <li class="slider_list_item"><img src="https://placehold.jp/0493cf/ffffff/768x432.png?text=number_04" alt="number_04"></li> </ul> </div> |
まず基本的なHTML。
ここにCSSで装飾をしていきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
.slider.type-01 { .js-slider { margin: 40px auto 0; } .slider_list { position: relative; } .slider_list_item { position: absolute; top: 0; left: 0; } } |
なにも難しいことはなく、ただ画像を重ねて配置しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
$(function () { // 画像一覧を定義する var slideBox = $('.type-01 .js-slider'); var slideList = $('.type-01 .slider_list'); // 画像を定義する var slideImage = $('.type-01 .slider_list_item'); // 最初の画像の幅と高さを取得 var imgHight = $(slideImage).eq(0).height(); var imgWidth = $(slideImage).eq(0).width(); // 最初のスライドを0とする var page = 0; // すべてのページから―1したもの最後のページとする var lastPage = $(slideImage).length - 1; // 最初の画像だけを表示する ① $(slideImage).hide(); $(slideImage).eq(page).show(); // スライダーに幅、高さを付与 $(slideBox).css('max-width', imgWidth); $(slideList).css('padding-top', imgHight); // ページ切り替えの関数を作成 ② function changePage() { $(slideImage).fadeOut(1000); $(slideImage).eq(page).fadeIn(1000); } //~ごとにイメージの切り替えを発火設定 ③ var time; function startTime() { time = setInterval(function () { if (page === lastPage) { page = 0; changePage(); } else { page++; changePage(); } }, 5000); } // ~ごとにイメージ切り替えの停止 function stopTime() { clearInterval(time); } //タイマースタート ④ startTime(); }); |
肝心の動きはすべてjQueryで構築しました。
かみ砕いて説明すると、
① ですべての画像を隠し、1枚目の画像を表示する。
② でこの仕組みの肝となるページ切り替えの関数を作成しました。
こちらもシンプルで、すべての画像をフィードアウトし、該当する画像をフィードインするといったもの。
③ で発火処理の作成。
ここで条件分岐が発生しました。
● 表示されているのが最後の画像だった場合
ページを0に戻し、② を実行。
つまり、最初のページをフィードイン。
● 表示されているのが最後のページ以外の場合
ページに1を足し、② を実行。
つまり次の画像をフィードイン
④ で実行。
考え方はシンプルですよね。
では次に矢印ボタンを付けた場合を考えてみました。
<prev>、<next>ボタン付きスライダー
まずはDEMOを参照してみてください。
今回は5秒待つ必要ありません。矢印ボタンを押してみてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<div class="slider type-02" id="02"> <section> <div class="heading type-02"> <h2><span class="hdg">「前」「次」ボタン付き ふわっとスライダー</span></h2> </div> <div class="js-slider"> <ul class="slider_list"> <li class="slider_list_item"><img src="https://placehold.jp/fffd34/ffffff/768x432.png?text=number_01" alt="number_01"></li> <li class="slider_list_item"><img src="https://placehold.jp/fe5409/ffffff/768x432.png?text=number_02" alt="number_02"></li> <li class="slider_list_item"><img src="https://placehold.jp/8701b0/ffffff/768x432.png?text=number_03" alt="number_03"></li> <li class="slider_list_item"><img src="https://placehold.jp/0493cf/ffffff/768x432.png?text=number_04" alt="number_04"></li> </ul> <div class="arrow_nav"> <p class="arrow_prev"><i class="fas fa-arrow-circle-left"></i></p> <p class="arrow_next"><i class="fas fa-arrow-circle-right"></i></p> </div> </div> </section> </div> |
追記箇所だけ書けば事足りるのですが、まるっと書きました。
追記したのは、
1 2 3 4 |
<div class="arrow_nav"> <p class="arrow_prev"><i class="fas fa-arrow-circle-left"></i></p> <p class="arrow_next"><i class="fas fa-arrow-circle-right"></i></p> </div> |
ここの部分。
長くなるのと、動きに関係してこないのでCSSは省略しました。
気になる方はデヴェロッパーツールで確認してみてください。
それでは肝心の動きの部分を。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
$(function () { // 画像一覧を定義する var slideBox = $('.type-02 .js-slider'); var slideList = $('.type-02 .slider_list'); // 画像を定義する var slideImage = $('.type-02 .slider_list_item'); // 最初の画像の幅と高さを取得 var imgHight = $(slideImage).eq(0).height(); var imgWidth = $(slideImage).eq(0).width(); // 最初のスライドを0とする var page = 0; // すべてのページから―1したもの最後のページとする var lastPage = $(slideImage).length - 1; // 最初の画像だけを表示する $(slideImage).hide(); $(slideImage).eq(page).show(); // スライダーに幅、高さを付与 $(slideBox).css('max-width', imgWidth); $(slideList).css('padding-top', imgHight); // ページ切り替えの関数を作成 function changePage() { $(slideImage).fadeOut(1000); $(slideImage).eq(page).fadeIn(1000); } //~ごとにイメージの切り替えを発火設定 var time; function startTime() { time = setInterval(function () { if (page === lastPage) { page = 0; changePage(); } else { page++; changePage(); } }, 5000); } // ~ごとにイメージ切り替えの停止 function stopTime() { clearInterval(time); } //タイマースタート startTime(); /*------------------ add Write ------------------*/ // 前へ、次へボタンを定義する var prevArrow = $('.type-02 .arrow_prev'); var nextArrow = $('.type-02 .arrow_next'); //前へボタンがクリックされた時 $(prevArrow).on('click', function () { stopTime(); startTime(); if (page === 0) { page = lastPage; changePage(); } else { page--; changePage(); } }); //次へボタンがクリックされた時 $(nextArrow).on('click', function () { stopTime(); startTime(); if (page === lastPage) { page = 0; changePage(); } else { page++; changePage(); } }); }); |
矢印部分に関するのは
1 2 3 |
/*------------------ add Write ------------------*/ |
以降の部分。
● 前へボタンがクリックされた時
まずはイメージの切り替えを停止、開始をする。
これをしないと、残り1秒で2枚目にスライドさせたとき、2枚目が1秒後にスライドしてしまうため、まずはリセットするという意味。
で、また条件分岐。
表示されているのが最初の画像の時は、最後の画像へ。
それ以外はページから1を引いたうえで、ページ切り替えの関数を実行。
次へボタンがクリックされたときはその逆の処理を実行する。
ドットナビゲーションを付けたスライダー
まずはDEMOを参照してみてください。
スライダーの下にある●〇〇〇がドットナビゲーション。
これがあれば何枚目のスライダーであと何枚スライドがあるのかわかるので便利ですよね。
1 2 3 4 5 6 |
<ul class="circle_nav"> <li><i class="fas fa-circle"></i></li> <li><i class="fas fa-circle"></i></li> <li><i class="fas fa-circle"></i></li> <li><i class="fas fa-circle"></i></li> </ul> |
今回は追記した部分だけを。
特に難しいところはないですね。
CSSも同じくごく平凡なので省略をし、肝心の部分に。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
$(function () { // 画像一覧を定義する var slideBox = $('.type-03 .js-slider'); var slideList = $('.type-03 .slider_list'); // 画像を定義する var slideImage = $('.type-03 .slider_list_item'); // 最初の画像の幅と高さを取得 var imgHight = $(slideImage).eq(0).height(); var imgWidth = $(slideImage).eq(0).width(); // 最初のスライドを0とする var page = 0; // すべてのページから―1したもの最後のページとする var lastPage = $(slideImage).length - 1; // 最初の画像だけを表示する $(slideImage).hide(); $(slideImage).eq(page).show(); // スライダーに幅、高さを付与 $(slideBox).css('max-width', imgWidth); $(slideList).css('padding-top', imgHight); // ページ切り替えの関数を作成 function changePage() { $(slideImage).fadeOut(1000); $(slideImage).eq(page).fadeIn(1000); } // サークルナビを定義 var circleNavItem = $('.type-03 .circle_nav li'); var clickDot = $('.type-03 .circle_nav li i'); var lastDot = $(circleNavItem).length - 1; var dot = 0; //console.log(lastDot) // サークルナビにクラスを付与 ① $(circleNavItem).each(function (i) { $(this).attr('class', 'circle_nav_item' + '-' + (i + 1)); $(circleNavItem).eq(0).addClass('is-active'); }); // ページ切り替えの関数を作成 サークルナビver function changeDot() { $(circleNavItem).removeClass('is-active'); $(circleNavItem).eq(dot).addClass('is-active'); } //~ごとにイメージの切り替えを発火設定 var time; function startTime() { time = setInterval(function () { if (page === lastPage) { page = 0; dot = 0; changePage(); changeDot(); } else { page++; dot++; changePage(); changeDot(); } }, 5000); } // ~ごとにイメージ切り替えの停止 function stopTime() { clearInterval(time); } //タイマースタート startTime(); // 前へ、次へボタンを定義する var prevArrow = $('.type-03 .arrow_prev'); var nextArrow = $('.type-03 .arrow_next'); //前へボタンがクリックされた時 $(prevArrow).on('click', function () { stopTime(); startTime(); if (page === 0) { page = lastPage; dot = lastDot; changePage(); changeDot() } else { page--; dot--; changePage(); changeDot(); } }); //次へボタンがクリックされた時 $(nextArrow).on('click', function () { stopTime(); startTime(); if (page === lastPage) { page = 0; dot = 0; changePage(); changeDot(); } else { page++; dot++; changePage(); changeDot(); } }); // サークルナビクリック時 ② $(clickDot).on('click', function () { var clickDotNum = $(clickDot).index(this); stopTime(); startTime(); if (clickDotNum === page) { return false; } else { page = clickDotNum; dot = clickDotNum; changePage(); changeDot(); } }); }); |
① でまずは最初のドットにクラスを付与しました。
CSSでクラスが付与されているドットの色を変更する必要があります。
そのままページ切り替え時のドットバージョン関数を作成してください。
ページ切り替えが起きた時、ドットからクラスを取り、該当のドットにクラスを付与するという関数。
② クリック時にドットが何番目か取得する。
クリックされたドットの順番が画像のスライドの順番と一致した場合は何もしない。
不一致の場合はドットの順番を代入し、処理をすることで、ふたつを連動させる。
―――――――――
上記のように基本コードを作成すればカスタマイズは簡単ですので、ぜひ試してみてください
例えば、横スライドするスライダー とか。
※chromeの現時点での最新バージョンしか動作確認していませんので、注意してください。