GWも変わらず勉強続けるのみ。
最近は暖かいのか寒いのかよくわからない季節ですね。
今回はSwiperやKeen-Sliderなどプラグインを使わず気合いでVanillaJsでスライドショーを作るという試みをしました。
なぜプラグインを使わないのか
最初はプラグインを使って質の良いスライドショーにするつもりだったんです。私はKeen-Sliderを使おうとnpmインストールを使ってどうたらこうたらしようとしました。
でも実際にインストールしてみるとオプションがたくさんあって何が何だか分からなくなり、「これもう自力で作った方が早いんじゃね?」と思ったのがきっかけです。もっとjsでのモジュールとかの扱い方に慣れてからにしようかなという次第。
こうなったら自力で…
早速本題に入ります。まずHTMLで要素を並べる。
同時にスライド用のボタンも実装します。画像の領域にボタンを入れたいので同じ箱に入れました。
<!-- 箱 -->
<div class="image_box">
<!-- スライド用のボタン -->
<div class="slidebtn_wrap">
<!-- ここのスタイルはあまり関係ないので省略 -->
<button class="prev"></button>
<button class="next"></button>
</div>
<!-- カルーセル -->
<div class="carousel">
<img src="ex1.png" alt="写真" class="__img">
<img src="ex2.png" alt="写真" class="__img">
<img src="ex3.png" alt="写真" class="__img">
<img src="ex4.png" alt="写真" class="__img">
<img src="ex5.png" alt="写真" class="__img">
</div>
</div>
通常はdisplay:none;
としてスライド時にjsによってopen
クラスが渡されたらその写真だけdisplay:block;
としたいので、CSSにスタイルを追加。
紛らわしくなるのでアニメーションとか装飾的なものはなしにします。
.__img {
display: none;
}
.__img.open{
display: block;
}
ここから自己流っぽくなりますが、JSにて
- 現在表示されている画像のインデックス番号を
x
とする。(初期値を0にセット)
- 進むボタン
next
をクリックするとx
番目の画像のopen
クラスを除去、x+1
番目(次)の画像にopen
クラスを追加するようにする。 - 上の処理が完了するたび
x+=1
を代入し足していく。
- 戻るボタン
prev
をクリックするとx
番目の画像のopen
クラスを除去、x-1
番目(前)の画像にopen
クラスを追加するようにする。 - 上の処理が完了するたび
x-=1
を代入し引いていく。
この処理でprev/next
ボタンを押し続けるといづれはx<0 / x>example.length
となり、
今回の例でいうと「0枚目の写真なんてないし6枚目もないから表示されないよ」状態になるので、それぞれに達したらprev
では5枚目の写真を表示しnext
では1枚目の写真を表示してリセット状態にしてあげれば良いのです。
以下のコードでできました。
//全ての__imgクラス(写真)を取得
const images = document.querySelectorAll('.__img');
//進む戻るボタン
const prev = document.querySelector('.prev');
const next = document.querySelector('.next');
let x = 0;
prev.addEventListener('click', ()=> {
if (x === 0) {
// スライドしてインデックス番号が0に達したらループ
// ここの-1はindex番号が0から開始するため
x = images.length - 1;
images[images.length - 1].classList.add('open');
images[0].classList.remove('open');
} else {
images[x].classList.remove('open');
images[x - 1].classList.add('open');
x -= 1;
}
},false);
next.addEventListener('click', ()=> {
if (x === images.length - 1) {
// スライドしてインデックス番号がMAXに達したらループ
x = 0;
images[0].classList.add('open');
images[images.length - 1].classList.remove('open');
} else {
images[x].classList.remove('open');
images[x + 1].classList.add('open');
x += 1;
}
},false);
仕組みとしては単純ですが、やや冗長になってしまったかもです。ここまで書いておいて「自信がない」という感想が正直なところですw
スライドの動きを加えるとなるとさらに複雑化しそうですな