JavaScriptのみでスライダーを実装する方法【コピペOK】

JavaScriptのみでスライダーを実装する方法【コピペOK】

SlickやSwiperなどのプラグインを使わずに、JavaScriptのみでスライダーを実装する方法を知りたい!

こう言った疑問に答えていきます。

Web制作でスライダーを実装する時、最近ではjQueryプラグインの「Slick」や「Swiper」で実装することが多いかと思います。

ただ、簡単にプラグインでスライダーを実装できても、その仕組みが理解できなければ意味がありません。また、jQueryはJavaScriptのライブラリでしかないので、jQueryで実装できても、JavaScriptで実装できなければ意味がありません。

そこで今回は、jQueryのプラグインを使用せずに、JavaScriptのみでスライダーを実装する方法について解説していきます。

では早速やっていきましょう。

JavaScriptのみでスライダーを実装する方法

スライダーの考え方

まず始めに、スライダーを実装する前に、スライダーの考え方について解説していきます。

イメージは下のような感じです。

  • 画像が表示される領域を起点に、CSSで画像を横並びにします。
  • 領域からはみ出た部分は「overflow: hidden; 」で非表示にします。
  • そしてNext( Prev)ボタンをクリックすると、画像のwidth分translateXで移動させる

と言った感じです。
では実際にコードを書いてみましょう!!

ファイルの準備

それではスライダーを実装していきましょう!
今回使用するHTMLファイル・CSSファイルはGitHubにアップしているので、活用してください。

今回は一般的なスライダーを実装していきます。
実装内容は以下の通りです。

  1. Next(Prev)ボタンの取得
  2. liタグのwidthを取得
  3. slider(ulタグ、liタグ一覧)の取得
  4. カウンターの設定
  5. イベントリスナー (next、prev)の設定

それでは1つずつみていきましょう!

Next(Prev)ボタンの取得

こちらは基本的なJavaScriptでの要素取得になりますので、そこまで説明はいらないかと思います。
今回は「querySelector」を使用していますが、idを設定して「getElementById」で取得しても問題ありません。

const next = document.querySelector(".next");
const prev = document.querySelector(".prev");

liタグのwidthを取得

次にliタグ(画像)のwidth値を取得していきます。
その前に先ほど同様、li要素を取得していきます。
取得できたら、clientWidthで要素のwidth値を取得します。
要素のサイズ取得には「getBoundingClientRect().width;」などもありますが、ここでは「clientWidth」で取得していきます。

今回は写真ではなく、背景の色を付けているだけですが、あくまでliタグのwidth値を取得するので、liタグの中に画像を挿入しても、基本的にはコードは変わりません。

const sliderwidth = document.querySelector(".sliderlist__item");
let width = sliderwidth.clientWidth;

slider(ulタグ、liタグ一覧)の取得

次にulタグ、liタグ一覧を取得していきます。
なぜこの2つを取得するかと言いますと、実際にボタンをクリックした時にスライドさせているのは、liタグ(画像)ではなくて、ulタグだからです。ulタグをliタグ(画像)のwidth値分translateXで移動させることで、あたかも画像が動いているかのように見えるのです。liタグの一覧を取得する理由は、後ほど説明します!

const sliderlist = document.querySelector(".sliderlist");
const sliderlist_item = document.querySelectorAll(".sliderlist__item")

カウンターの設定

カウンターは、ulタグを移動させる時に使用します。
Next(Prev)ボタンをクリックした時に、liタグ(画像)のwidth値分スライドさせるのですが、1回クリックした時は、正常にwidth値分スライドするのですが、2回目以降ボタンをクリックした時、もうすでにliタグ(画像)のwidth値分スライドしてしまっている(translateXで移動させる値が変わらない)ので、ulタグがスライドしません。
そこでカウンターを使用して、Next(Prev)ボタンをクリックしたら、カウンターを1ずつ増やす( Prevの場合は、1ずつマイナスする)ことで、translateXの値を「liタグ(画像)のwidth値 × カウンター」で変化させてスライドさせます。

実際に、スライダー実装後にデベロッパーツールでulタグのtranslateX値を見たほうが早いかと思います。

let counter = 0;

イベントリスナー (next、prev)の設定

そして最後にイベントの登録をしていきます。
今回イベントを発生させる箇所は、「Nextボタン」と「Prevボタン」の2箇所です。

「addEventListener」を使ってclick時の処理を書いていきます。
まず始めに、「Prevボタンの表示」「ulタグのtransitionの設定」「カウンターの設定」「ulタグのtranslateXの設定」を書いていきます。

next.addEventListener("click", function(){
    prev.style.display = "block";
    sliderlist.style.transition = ".3s";
    counter ++;
    sliderlist.style.transform = "translateX("+ (- width * counter) + "px)";
});

「Prevボタンの表示」は、CSSで予めをボタンを非表示にしているので(前の画像がないので、クリックできないようにするために非表示にしています)、Nextボタンをクリックした時に、Prevボタンを表示させて、前のスライドに戻せるようにしてあげます。

「ulタグのtransitionの設定」は、スライドを滑らかにするためです。こちらの数値は、好きなように変更してもらって構いません。

「カウンターの設定」は、先ほど説明したように、スライドさせるために必要なものです。初期値が0なので、1回クリックするたびに、カウンターを1ずつ増やしていきます。

最後に「ulタグのtranslateXの設定」は、こちらも先ほど説明したように、ボタンをクリックすると、「liタグ(画像)のwidth値 × カウンター」でスライドさせます。translateXをプラスにすると、逆方向にスライドしてしまうので、必ずマイナス値にします。

次に、最後のliタグ(画像)が表示された時の処理を書いていきます。
ここでは、addEventListenerの「transitionend」というイベントを使用して、if文でtransitionが終わった時に、もしカウンターの値がliタグの数(画像の数)からマイナス1した値であったら、「ulタグのtransitionをnoneにする」「Nextボタンを非表示する」という処理を書きます。

ここで先ほど説明した「liタグの一覧」を使用します。
なぜわざわざ「liタグの数(画像の数)からマイナス1した値」という処理を書いているかというと、今後のメンテナンスを考慮してこのような処理を書いています。

スライドする回数を計算して数値を指定しても同じ動きを実装できますが、別でliタグ(画像)を追加するとなった場合、HTML側でliタグを追加するだけでなく、この数値までも変更しなくてはいけなくなります。
ですが、予め「liタグの数(画像の数)からマイナス1した値」という処理を書いておけば、カウンターの数を自動で計算してくれるので、わざわざここの処理をいじる必要性がなくなります。

こう言った理由から「liタグの数(画像の数)からマイナス1した値」という処理を書いています。

sliderlist.addEventListener("transitionend", function(){
   if(counter == sliderlist_item.length - 1){
       sliderlist.style.transition = "none";
       next.style.display = "none";
})

「ulタグのtransitionをnoneにする」は、とても簡単でnoneにするだけです。

「Nextボタンを非表示する」は、こちらも簡単でnoneにするだけです。

ここまでが、Nextボタンのイベント処理になります。
PrevボタンもNextボタンと同じような処理を書いていきます。

prev.addEventListener("click", function(){
   next.style.display = "block";
   sliderlist.style.transition = ".3s";
   counter --;
   sliderlist.style.transform = "translateX("+ (- width * counter) + "px)";

   sliderlist.addEventListener("transitionend", function(){
       if(counter == sliderlist_item.length - sliderlist_item.length){
           sliderlist.style.transition = "none";
           prev.style.display = "none";
       }
    })
});

説明は省略しますが、Nextボタンと大きく違う点は「クリックした時にカウンターをマイナスにする」という処理と、if文の条件式の「liタグの数(画像の数)からliタグの数(画像の数)を引いた値」という2箇所だけです。

ボタン連打対策

スライダー自体は、このままでも問題なく動きますが、ボタンを連打した時に、スライダーが止まらないという欠点があります。
この対策として以下のコードを追加するとその欠点を解消してくれます。

next.addEventListener("click", function(){
   if(counter == sliderlist_item.length - 1) return;
   //以下省略
});

prev.addEventListener("click", function(){
   if(counter == sliderlist_item.length - sliderlist_item.length) return;
   //以下省略
});

これはあくまで参考程度のものです。他にも「setTimeout」を使用した方法などもありますので、自分にあったものを試して見てください!

まとめ

今回は、JavaScriptを使用した一般的なスライダーの実装方法について解説してきました。
jQueryを使用せずにJavaScriptのみでスライダーを実装する方法はいくつかあるので、自分にあったものを試してみてください。

では今回は以上になります。