こんにちは。
前回からの続きになります。https://qiita.com/amanomunt/items/432cbf9c5a654695a720
nextボタンとprevボタンの処理
まずは次に進む [ next ] ボタンです。
ボタンにはhtml上でIDをつけてあるので、それを取得してクリックイベントを追加します。
イベントの処理は、
1.現在のカレントクラスを外す(removeCurremtClass関数呼び出し)
2.カレントナンバーを一つ追加(次に進む)
3.それに合わせてメイン画像を差し替え(setMainImage関数呼び出し)
const next = document.getElementById('next');
next.addEventListener('click', () => {
removeCurremtClass(); // カレントクラスを外す
currentNum++; // カレントナンバーに1足す(更新)
addCurremtClass(); // 更新したインデックスにカレントクラスを追加する
setMainImage(images[currentNum]); // メイン画像をきりかえる
});
ただしこのままだと、サムネイルの最後までいったうえでnextボタンを押すとエラーになるので、そのあたりを修正します。
ついでに、最後まで行ったら次は先頭に戻るように修正しましょう。
const next = document.getElementById('next');
next.addEventListener('click', () => {
removeCurremtClass();
currentNum++;
if (currentNum === images.length) { // currentNumがlength=配列要素数と同じになったら
currentNum = 0; // 0に戻す
}
addCurremtClass();
setMainImage(images[currentNum]);
});
ここでif文の条件currentNum === images.length
にちょっとした解説です。
images配列のlengthは8つなのですが、currentNum
は0から7の8つとなります。
したがって、配列8番目を選択してる時のcurrentNum
は7ということになりますね。
そのため、最後の要素の時にnextを押すとcurrentNum
が8になり、images.length
と同じになる。
そうなったら0番目に戻ろうね、という処理になります。
同様に [ prev ] ボタンの処理を書きます。
異なる点はcurrentNumを減らすことと、if文です。
const prev = document.getElementById('prev');
next.addEventListener('click', () => {
removeCurremtClass();
currentNum--; // カレントナンバーを1引く(更新)
if (currentNum < 0) { // currentNumが0より小さくなったら
currentNum = images.length - 1; // 最後の要素に飛ばす
}
addCurremtClass();
setMainImage(images[currentNum]);
});
今度は0より小さくなったら要素の最後に飛ばす処理にします。
上記のように、8番目の要素はcurrentNum
としては7になるので、images.length
の8から1引くので、currentNum = images.length - 1;
となるんですね。
Playボタンでスライドショーを再生できるようにする
まずはplay要素を取得し、イベントを追加しましょう。
処理もplaySlideShow
という関数を作りそこにまとめます。
const play = document.getElementById('play'); // play要素取得
play.addEventListener('click', () => {
playSlideShow(); // スライドショー開始関数呼び出し
});
playSlideShow
関数を書いていきましょう。
スライドショーとは要は、自動的に次へ行くのだから、nextの処理を自動化させれば良いでしょう。
一定時間ごとにnextをclickすることを繰り返せば良いので、setTimeout
関数を使います。ここでは確認のために、少し早く300ミリ秒ごとにとします。
function playSlideShow() {
setTimeout(() => { // 一定時間でループ
next.click(); // nextボタンクリック時と同じ動作
playSlideShow(); // 再度呼び出し
}, 300);
}
次に、スライドショーを再生したら停止させるための[ stop ]ボタンの処理を書きます。
一番最初に書いたhtmlの中でもともと[ stop ]ボタンを用意してあり、hidden
クラスというdisplay:none;
属性をつけて隠してあります。
それと[ play ]ボタンにhidden
クラスを使って、再生中、停止中で表示・非表示を切り替えます。
まず[ pause ]ボタンを取得します。
そして[ play ]ボタンのクリックイベント内で、各ボタンのhiddden
クラスを操作します。
const play = document.getElementById('play');
const pause = document.getElementById('pause'); // pause要素取得
play.addEventListener('click', () => { // playボタンが押されたら
play.classList.add('hidden'); // playボタンを非表示に
pause.classList.remove('hidden'); // pauseボタンを表示させる
playSlideShow();
});
次に[ pause ]ボタンの処理を書きます。
Pauseボタンでスライドショーを停止させる
まずはひとつずつ、[ pause ]ボタンを押されたときの表示・非表示クラスの切り替え処理を書きます。
pause.addEventListener('click', () => { // pauseボタンが押されたら
pause.classList.add('hidden'); // playボタンを表示させる
play.classList.remove('hidden'); // pauseボタンを非表示に
});
スライドショーを停止させるにはsetTimeout
を停止させるclearTimeout
を使います。
ただしclearTimeout
はsetTimeout
の返り値が必要になるので、先程書いたsetTimeout
の箇所で変数宣言しましょう。
let timeouId; // setTimeout の返り値が必要になるので宣言
function playSlideShow() {
timeouId = setTimeout(() => { // timeouIdにsetTimeoutの返り値を入れる
next.click();
playSlideShow();
}, 300);
}
pause.addEventListener('click', () => {
pause.classList.add('hidden');
play.classList.remove('hidden');
clearTimeout(timeouId); // setTimeout の返り値を取得し、それをストップ
});
以上でスライドショーの完成です。
こうして順序立てて書いていくことで、勉強し始めた頃にぱっと見てもわからなかったことが少しずつわかるようになってきました。
そしていくつか簡単ながらプログラムを書いたことで、ある程度の流れを知ることができてきたように思えます。
まだまだ初心者なので、ん?と思って進めないことが多々ありますが、それもアウトプットしていくことで理解を深めると同時に、これをご覧になってくださった方が同じ疑問を持った際、少しでもお役に立てればと考えています。
今後も簡単なプログラムを学びながら、少し自分の色を入れていこうと思います。
どうぞ宜しくお願い致します。
完成したコード
'use strict';
{
let images = [
{url: 'img/pic00.jpg', txt: {name: '紺瑠璃', color: '#164a84'},},
{url: 'img/pic01.jpg', txt: {name: '天色', color: '#2ca9e1'},},
{url: 'img/pic02.jpg', txt: {name: '翡翠色', color: '#38b48b'},},
{url: 'img/pic03.jpg', txt: {name: '浅緑', color: '#88cb7f'},},
{url: 'img/pic04.jpg', txt: {name: '萌黄', color: '#aacf53'},},
{url: 'img/pic05.jpg', txt: {name: '山吹茶', color: '#c89932'},},
{url: 'img/pic06.jpg', txt: {name: '一斤染', color: '#f5b199'},},
{url: 'img/pic07.jpg', txt: {name: '浅蘇芳', color: '#a25768'},},
]
let currentNum = 0;
const name = document.getElementsByClassName('name');
const color = document.getElementsByClassName('color');
function setMainImage(image) {
document.querySelector('main img').src = image.url;
document.querySelector('main .name').textContent = `${image['txt'].name}`;
document.querySelector('main .color').innerHTML = `カラーコード:<strong>${image['txt'].color}</strong>`;
}
setMainImage(images[currentNum]);
function removeCurremtClass() {
document.querySelectorAll('.thumbnails li')[currentNum].classList.remove('current');
}
function addCurremtClass() {
document.querySelectorAll('.thumbnails li')[currentNum].classList.add('current');
}
const thumbnails = document.querySelector('.thumbnails');
images.forEach((image, index) => {
const li = document.createElement('li');
if (index === currentNum) {
li.classList.add('current');
}
li.addEventListener('click', () => {
setMainImage(image);
removeCurremtClass();
currentNum = index;
addCurremtClass();
});
const img = document.createElement('img');
img.src = image.url;
li.appendChild(img);
thumbnails.appendChild(li);
});
const next = document.getElementById('next');
next.addEventListener('click', () => {
removeCurremtClass();
currentNum++;
if (currentNum === images.length) {
currentNum = 0;
}
addCurremtClass();
setMainImage(images[currentNum]);
});
const prev = document.getElementById('prev');
prev.addEventListener('click', () => {
removeCurremtClass();
currentNum--;
if (currentNum < 0) {
currentNum = images.length - 1;
}
addCurremtClass();
setMainImage(images[currentNum]);
});
let timeouId;
function playSlideShow() {
timeouId = setTimeout(() => {
next.click();
playSlideShow();
}, 300);
}
const play = document.getElementById('play');
const pause = document.getElementById('pause');
play.addEventListener('click', () => {
play.classList.add('hidden');
pause.classList.remove('hidden');
playSlideShow();
});
pause.addEventListener('click', () => {
pause.classList.add('hidden');
play.classList.remove('hidden');
clearTimeout(timeouId);
});
}