JavaScript - 自動で画像が切り替わるスライドショーの作り方
複数の画像を順番に表示するスライドショーを作ります。一定の間隔で自動的に画像が変わるだけでなく、クリックして表示を切り替えることもできるようにコーディングします。
クリックもできる自動再生スライドショー
今回紹介するのは、一定間隔で画像が切り替わるスライドショーの作り方です。画像の下にナビケーションボタンを配置し、自動再生している間にも手動で画像を切り替えることができるようにします。
この記事を読むと分かること
document.createElement( )
appendChild()
classList.add()
classList.remove()
forEach()
setInterval()
clearInterval()
サンプルプロジェクト
最初に、スライドショーの動きを確認しておきましょう。画像の下にあるドットは、何番目の画像が表示されているのかを示すナビゲーションボタンです。表示されている画像のボタンはオレンジ色になります。画像は自動で切り替わるほか、ボタンをクリックして切り替えることもできます。
HTML
まずは HTML です。画像 <img>
はお好みのものをいくつか用意し、src
属性に画像へのパスを書きます。ナビゲーションコンテナ nav-container <div>
は、この段階では空っぽです。このあとの JavaScript で、ナビゲーションボタンを作っていきます。
<div class="slider-container">
<div class="image-container">
<img src="https://images.unsplash.com/photo-1481349518771-20055b2a7b24?w=900&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8NDd8fGZydWl0ZXN8ZW58MHx8MHx8fDA%3D" alt="one banana">
<img src="https://images.unsplash.com/photo-1528821128474-27f963b062bf?w=900&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MzR8fGZydWl0ZXN8ZW58MHx8MHx8fDA%3D" alt="two cherries">
<img src="https://images.unsplash.com/photo-1457803097035-3ace37af34a7?w=900&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTEwfHxmcnVpdGVzfGVufDB8fDB8fHww" alt="three apples">
<img src="https://images.unsplash.com/photo-1595475207225-428b62bda831?w=900&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTU0fHxmcnVpdGVzfGVufDB8fDB8fHww" alt="four slices of watermelon">
</div>
<!-- ナビゲーションコンテナ -->
<div class="nav-container"></div>
</div>
CSS
続いて CSS です。表示する画像とナビゲーションボタンの色は、JavaScript でクラスの付け外しすることで切り替えていきます。表示する画像に付け加えるクラスを image-active
、ボタンの色を変えるためのクラスを btn-active
として用意しておきましょう。
body {
margin: 0;
padding: 0;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-color: #454545;
}
.slider-container {
position: relative;
display: flex;
width: 800px;
height: 500px;
border: 5px solid lightgray;
}
/* 画像コンテナ */
.image-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 90%;
object-fit: cover;
}
/* 画像 */
img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
opacity: 0; /* 透明(非表示)*/
transition: opacity 0.5s;
}
/* 画像を表示するためのクラス */
img.image-active {
opacity: 1; /* 不透明(表示)*/
transition: opacity 0.5s;
}
/* ナビゲーションコンテナ */
.nav-container {
position: absolute;
bottom: 0;
width: 100%;
height: 10%;
display: flex;
justify-content: center;
align-items: center;
background-color: lightgray;
}
/* 新しく作成したボタンに追加するクラス */
.nav-btn {
height: 20px;
width: 20px;
display: inline-block;
margin: 10px;
background-color: #0d7df5; /* 青色 */
border-radius: 50%;
border: none;
cursor: pointer;
}
/* ボタンの色を変えるためのクラス */
.nav-btn.btn-active {
background-color: #f99f3e; /* オレンジ色 */
}
.nav-btn:hover{
box-shadow: 0 0 5px 3px white;
}
ブラウザには下のように表示されます。画像は opacity: 0
で透明にしてあるので見えません。
JavaScript
JavaScript のコーディングは、大きく3段階に分けて考えていきますよ。
- 要素の取得と変数の宣言
- ボタンを作成しクリックで画像を切り替える
- 自動で次の画像へ切り替える
要素の取得と変数の宣言
最初に、JavaScript で動きをつけられるように要素を取得しておきましょう。
- 用意したすべての画像を
querySelectorAll()
メソッドでまとめて取得し、変数images
に格納します。 - ボタンを表示するエリアを、変数
navContainer
で参照できるようにしておきます。ボタンはこのあと JavaScript で生成していきます。
//すべての画像
const images = document.querySelectorAll('img');
//ナビゲーションコンテナ
const navContainer = document.querySelector('.nav-container');
次に行うのは、変数の宣言です。
- 用意した画像の総数を
images.length
で取得し、変数totalImages
に格納します。 - 表示する画像を指定する変数を
imageIndex
とし、0
で初期化しておきます。 - 自動再生に使うタイマーを入れておくための変数
interval
を用意します。タイマーをキャンセルするときにこの変数が必要になります。
//画像の総数
const totalImages = images.length;
//表示する画像を指定するインデックス
let imageIndex = 0;
//タイマー
let interval;
要素の取得と変数の宣言ができたら、スライドショーに動きをつけるためのコードを書いていきましょう。
ボタンを作成しクリックで画像を切り替える
今回作るスライドショーは、自動再生機能だけでなく、クリックに反応するナビゲーションボタンも設置しますよ。まずは、クリックで画像を切り替えられるようにしていきます。次の手順でコードを書いていきましょう。
- 画像と同じ数のボタンを作る
- すべてのボタンにクリックイベントを追加する
- 画像とボタンを更新する
画像と同じ数のボタンを作る
画像の下部に設置するナビゲーションボタンは、画像と同じ数だけ必要です。ボタンは HTML で作っておくこともできますが、画像の増減に簡単に対応できるように、今回は JavaScript で作っていきますよ。
JavaScript で新しく要素を作るため使うのは、document.createElement()
メソッドです。document.createElement( )
メソッドは、括弧 ()
に指定されたタグの名前の要素を生成します。ここでは、ナビゲーションボタンを <button>
要素で作ります。
//新しいボタン要素を作成
const button = document.createElement('button');
新しく作ったボタンには、 classList.add()
メソッドでクラスを追加します。追加するクラス nav-btn
の内容は、先ほどの CSS を参照してくださいね。
const button = document.createElement('button');
//新しく作成したボタンにクラスを追加
button.classList.add('nav-btn');
続けて、appendChild()
メソッドを使って、ボタンを表示するエリアである navContainer
に追加します。
const button = document.createElement('button');
button.classList.add('nav-btn');
//新しく作成したボタンをナビゲーションコンテナに追加
navContainer.appendChild(button);
以上3つの文を、for
文を使って繰り返し処理し、画像と同じ数のボタンを作りましょう。
//画像と同じ数のボタンを作成
for (let i = 0; i < totalImages; i++) {
const button = document.createElement('button');
button.classList.add('nav-btn');
navContainer.appendChild(button);
}
for
文について詳しくは以下の記事をご覧ください。
ブラウザには下のように表示されます。用意した画像の枚数によってボタンの数も変わりますよ。
すべてのボタンにクリックイベントを追加する
ナビゲーションボタンを作ったら、今度は、一つひとつのボタンをクリックできるようにしていきます。そのために、生成したすべてのボタンをまとめて取得し、変数 buttons
に格納しましょう。
//すべてのボタンをまとめて取得
const buttons = document.querySelectorAll('.nav-btn');
forEach()
メソッドを使って、すべてのボタンにクリックイベントを追加します。括弧 ()
に指定する関数の内容は、「ボタン一つひとつにクリックイベントを追加して、クリックされたボタンと同じインデックスの画像を表示する」という処理です。
//すべてのボタンにクリックイベントを追加
buttons.forEach(() => {
/*==============================================
ボタン一つひとつにクリックイベントを追加、
クリックされたボタンと同じインデックスの画像を表示する処理;
==============================================*/
});
関数には二つの引数を指定します。処理の対象となる要素を受け取る button
と、処理の対象となっている要素のインデックスを受け取る index
です。
//二つの引数を指定
buttons.forEach((button,index) => {
/*==============================================
ボタン一つひとつにクリックイベントを追加、
クリックされたボタンと同じインデックスの画像を表示する処理;
==============================================*/
});
ボタン一つひとつにクリックイベントを追加するコードは、以下のようになります。ボタンがクリックされたら、クリックされたボタンと同じインデックスの画像を表示するようにしましょう。
buttons.forEach((button,index) => {
//ボタン一つひとつにクリックイベントを追加
button.addEventListener('click',() => {
/*==============================================
クリックされたボタンと同じインデックスの画像を表示する処理;
==============================================*/
});
});
クリックされたボタンと同じインデックスの画像を表示するためには、クリックされたボタンのインデックス index
を、表示する画像のインデックス imageIndex
に代入します。そうすることで、最初のボタンがクリックされたら最初の画像を、2番目のボタンがクリックされたら2番目の画像を指定できるようになりますよ。
buttons.forEach((button,index) => {
button.addEventListener('click',() => {
//表示する画像のインデックスをクリックされたボタンのインデックスと同じにする
imageIndex = index;
});
});
ボタンをクリックして表示する画像を指定したら、関数 updateSlider
を実行します。関数 updateSlider
は、画像とボタンを更新する関数で、このあと定義します。
buttons.forEach((button,index) => {
button.addEventListener('click',() => {
imageIndex = index;
//画像とボタンを更新
updateSlider();
});
});
ここまでで、画像と同じ数のナビゲーションボタンを作成し、ボタンをクリックして表示する画像を指定できるようになりました。
画像とボタンを更新する
ここからは、画像とボタンを更新する関数 updateSlider
を定義していきましょう。内容は、「表示する画像を切り替えて、それと一致するボタンの色を変える」という処理です。
//画像とボタンを更新
function updateSlider() {
/*======================================
表示する画像を切り替えてボタンの色を変える処理;
======================================*/
}
画像とボタンの更新は、クラスの付け外しをすることで行います。まずは、classList.remove()
メソッドを使って、すべての画像から image-active
を、すべてのボタンから btn-active
クラスを取り外しましょう。これによって、一旦、すべての画像が非表示に、すべてのボタンが青色になりますよ。
function updateSlider() {
//すべての画像からimage-activeクラスを取り外す
images.forEach(image => {
image.classList.remove('image-active');
});
//すべてのボタンからbtn-activeクラスを取り外す
buttons.forEach(button => {
button.classList.remove('btn-active');
});
}
次に、classList.add()
メソッドで、表示する画像に image-active
クラスを、それと同じインデックスのボタンに btn-active
クラスを追加します。これによって、指定された画像が表示され、それと一致するボタンがオレンジ色になりますよ。表示する画像は、変数 imageIndex
を使って images[imageIndex]
のように指定します。色を変えるボタンも同じです。
function updateSlider() {
images.forEach(image => {
image.classList.remove('image-active');
});
buttons.forEach(button => {
button.classList.remove('btn-active');
});
//表示する画像を変数imageIndexで指定しimage-activeクラスを追加
images[imageIndex].classList.add('image-active');
//色を変えるボタンを変数imageIndexで指定しbtn-activeクラスを追加
buttons[imageIndex].classList.add('btn-active');
}
以上で、画像とボタンを更新する関数 updateSlider
を定義できました。この段階では、ボタンをクリックすることでのみ画像を切り替えることができます。
自動で次の画像へ切り替える
さて、続いては、自動再生機能です。一定時間毎に次の画像へ自動的に切り替わるようにします。次の手順でコードを書いていきましょう。
- 次の画像を指定して表示する
- タイマーを設定し一定時間毎に自動で切り替える
- タイマーをキャンセルしタイミングのズレを直す
次の画像を指定して表示する
次の画像を順番に表示するために、関数 nextImage
を次のように定義しましょう。
- 変数
imageIndex
の値を1増やして、次の画像を指定する - もし、指定する画像が最後の画像のインデックスより大きいなら
- 変数
imageIndex
の値を0
にして最初の画像を指定する - 画像とボタンを更新する
//次の画像を指定して表示
function nextImage() {
imageIndex++;
if (imageIndex > totalImages - 1) {
imageIndex = 0;
}
//画像とボタンを更新
updateSlider();
}
次の画像を指定する方法については、以下の記事で詳しく解説しているので参考にしてください。
タイマーを設定し一定時間毎に自動で切り替える
自動再生の関数 autoPlay
を定義します。一定時間で自動的に画像を切り替えるために、setInterval()
メソッドで関数 nextImage
を呼び出しましょう。ここでは呼び出す間隔を 3000
とし、3秒毎に次の画像へ切り替わるようにします。
//次の画像へ自動再生
function autoPlay() {
interval = setInterval(nextImage, 3000);
}
タイマーをキャンセルしタイミングのズレを直す
さらに、タイマーを一旦キャンセルする関数 resetInterval
を用意します。これは、ボタンのクリックで画像を切り替えた場合に、自動再生のタイミングがズレるのを直すための関数です。
clearInterval()
メソッドの括弧 ()
内に、自動再生のタイマーを格納した変数 interval
を指定すると、タイマーを停止することができます。その後再び自動再生の関数 autoPlay
を呼び出すことで、3秒間隔での自動再生が再開されます。
//自動再生を一旦停止してから再び再生
function resetInterval() {
clearInterval(interval);
autoPlay();
}
この関数 resetInterval
は、ボタンのクリックで画像を切り替えたときに必要になるので、以下のようにコードを追加しましょう。
//すべてのボタンにクリックイベントを追加
buttons.forEach((button,index) => {
button.addEventListener('click',() => {
imageIndex = index;
updateSlider();
//自動再生を一旦停止してから再び再生
resetInterval();
});
});
スライドショーを開始する
さて、これが最後のコードです。画像とボタンを更新する関数 updateSlider
と、自動再生する関数 autoPlay
を呼び出して、スライドショーを開始しましょう。
//スライドショーを開始
updateSlider();
autoPlay();
完成コード
クリックでの画像切り替えも可能な、自動再生するスライドショーのコードが完成です。
/**********************/
/* スライドショーのコード */
/**********************/
const images = document.querySelectorAll('img');
const navContainer = document.querySelector('.nav-container');
const totalImages = images.length;
let imageIndex = 0;
let interval;
//画像と同じ数のボタンを作成
for (let i = 0; i < totalImages; i++) {
const button = document.createElement('button');
button.classList.add('nav-btn');
navContainer.appendChild(button);
}
//作成したボタンを操作できるようにすべてのボタンをまとめて取得
const buttons = document.querySelectorAll('.nav-btn');
//すべてのボタンにクリックイベントを追加
buttons.forEach((button,index) => {
button.addEventListener('click',() => {
imageIndex = index;
updateSlider();
resetInterval();
});
});
//画像とボタンを更新
function updateSlider() {
images.forEach(image => {
image.classList.remove('image-active');
});
buttons.forEach(button => {
button.classList.remove('btn-active');
});
images[imageIndex].classList.add('image-active');
buttons[imageIndex].classList.add('btn-active');
}
//次の画像を指定して表示
function nextImage() {
imageIndex++;
if (imageIndex > totalImages - 1) {
imageIndex = 0;
}
updateSlider();
}
//次の画像へ自動再生
function autoPlay() {
interval = setInterval(nextImage, 3000);
}
//自動再生を一旦停止してから再び再生
function resetInterval() {
clearInterval(interval);
autoPlay();
}
//スライドショーを開始
updateSlider();
autoPlay();
See the Pen JavaScript - Automatic and Manual Slideshow by Pyxofy (@pyxofy) on CodePen.
まとめ
今回は、一定の間隔で自動的に切り替わるだけでなく、クリックして表示する画像を変えることもできるスライドショーの作り方を紹介しました。
コードのポイントをまとめると以下のようになります。
- 画像と同じ数だけ必要な
<button>
要素を JavaScript で生成 - 複数の画像やボタンに対して同じ処理を実行するために
forEach()
メソッドを利用 - 画像の表示/非表示やボタンの色はクラスの付け外しによって切り替えを実行
- 自動再生のタイミングは一旦タイマーを停止してから再開することで調整
最後まで読んでいただき、ありがとうございます。この記事をシェアしてくれると嬉しいです!
SNSで Pyxofy とつながりましょう! LinkedIn・ Threads・ Mastodon・ X (Twitter) @pyxofy・ Facebook