読み込み中...

JavaScriptでなめらかなフェードインスライドショーを実装する方法12選

JavaScriptでなめらかなスライドショーを実装する JS
この記事は約40分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

●JavaScriptスライドショーとは?

スライドショーといえば、Webサイトに動きと華やかさを与えてくれる要素の1つですよね。

訪問者の目を引き、コンテンツに興味を持ってもらうのにとても効果的です。

そんなスライドショーをJavaScriptで実装する方法について、これから詳しく解説していきたいと思います。

○スライドショーの基本的な仕組み

まず、スライドショーの基本的な仕組みについて理解しておきましょう。

スライドショーは、複数の画像を一定の時間間隔で切り替えて表示することで、動きのある演出を作り出します。

この切り替えのタイミングは、JavaScriptのタイマー機能を使ってコントロールします。

簡単に言うと、スライドショーは次のようなステップで実現されています。

  1. HTML内に複数の画像要素を配置する
  2. CSSを使って、画像要素を重ねて表示するようにスタイリングする
  3. JavaScriptを使って、一定時間ごとに表示する画像を切り替える

画像の切り替え方法には、大きく分けて「フェードイン・フェードアウト」と「スライド」の2種類があります。

フェードインは画像をゆっくりと浮かび上がらせるように表示し、フェードアウトは反対にゆっくりと消えていくように非表示にします。

一方、スライドは画像を横にスクロールするように切り替える方法です。

○JavaScriptを使う利点

ここで、JavaScriptを使ってスライドショーを実装する利点について触れておきましょう。

JavaScriptを使う最大のメリットは、動的で柔軟性の高いスライドショーを作れることです。

例えば、ユーザーの操作に応じてスライドショーの動作を変化させたい場合、JavaScriptなら簡単に実現できます。

「次へ」「前へ」ボタンをクリックした時だけ画像を切り替えたり、マウスオーバーで一時停止したりといった具合です。

また、スライドショーをレスポンシブ対応させることも、JavaScriptを使えばそれほど難しくありません。

画面サイズに合わせて画像のサイズを動的に変更することで、どんなデバイスでも最適な表示を実現できるのです。

このように、JavaScriptを使うことでスライドショーに様々な機能を付加することができます。

Webサイトに動きと interactivity を持たせ、ユーザーエンゲージメントを高めるのに役立つでしょう。

●フェードインスライドショーの実装

さて、JavaScriptを使ってスライドショーを作る醍醐味は、何といってもアニメーション効果を加えられることですよね。

中でも人気なのが、画像をゆっくりと浮かび上がらせるようにフェードインさせるエフェクトです。

フェードインスライドショーを実装するには、まず複数の画像を重ねて配置し、JavaScriptで一定時間ごとに不透明度(opacity)を変化させていきます。

不透明度を0から1へ滑らかに変化させることで、フェードインのアニメーションが表現できるというわけです。

では早速、シンプルなフェードインスライドショーのサンプルコードを見ていきましょう。

○サンプルコード1:シンプルなフェードイン

<div id="slideshow">
  <img src="image1.jpg" alt="画像1">
  <img src="image2.jpg" alt="画像2">
  <img src="image3.jpg" alt="画像3">
</div>
#slideshow {
  position: relative;
  width: 100%;
  height: 400px;
}

#slideshow img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 1s ease-in-out;
}

#slideshow img.active {
  opacity: 1;
}
const slideshow = document.getElementById('slideshow');
const images = slideshow.getElementsByTagName('img');
let currentIndex = 0;

function showNextImage() {
  images[currentIndex].classList.remove('active');
  currentIndex = (currentIndex + 1) % images.length;
  images[currentIndex].classList.add('active');
}

setInterval(showNextImage, 3000);

コードを詳しく見ていきますね。

HTMLでは、<div>要素の中に<img>要素を複数配置しています。

これがスライドショーに表示する画像になります。

CSSでは、#slideshowpositionrelativeに設定し、<img>要素のpositionabsoluteにすることで、画像を重ねて表示するようにしています。

また、opacityを0に設定して初期状態では非表示にし、transitionプロパティでフェードインのアニメーションを指定しています。

JavaScriptでは、setInterval()を使って一定時間(ここでは3000ミリ秒=3秒)ごとにshowNextImage()関数を呼び出しています。

この関数内で、現在表示中の画像のactiveクラスを外し、次の画像にactiveクラスを付与することで、フェードインしながら画像が切り替わるようになっています。

実行結果

<!-- 3秒ごとに画像がフェードインしながら切り替わる -->
<div id="slideshow">
  <img src="image1.jpg" alt="画像1" class="active">
  <img src="image2.jpg" alt="画像2">
  <img src="image3.jpg" alt="画像3">
</div>

シンプルながら、とてもスタイリッシュなスライドショーが完成しましたね!

○サンプルコード2:ボタン付きフェードイン

フェードインスライドショーにもう一工夫加えて、「次へ」「前へ」ボタンを追加してみましょう。

ユーザーが任意のタイミングで画像を切り替えられるようになります。

サンプルコードはこちら。

<div id="slideshow">
  <img src="image1.jpg" alt="画像1">
  <img src="image2.jpg" alt="画像2">
  <img src="image3.jpg" alt="画像3">
  <button id="prev">&lt;</button>
  <button id="next">&gt;</button>
</div>
const slideshow = document.getElementById('slideshow');
const images = slideshow.getElementsByTagName('img');
const prevButton = document.getElementById('prev');
const nextButton = document.getElementById('next');
let currentIndex = 0;

function showImage(index) {
  images[currentIndex].classList.remove('active');
  currentIndex = (index + images.length) % images.length;
  images[currentIndex].classList.add('active');
}

function showNextImage() {
  showImage(currentIndex + 1);
}

function showPrevImage() {
  showImage(currentIndex - 1);
}

prevButton.addEventListener('click', showPrevImage);
nextButton.addEventListener('click', showNextImage);

setInterval(showNextImage, 3000);

HTMLに<button>要素を追加し、CSSでボタンのスタイルを調整しています。

JavaScriptでは、showImage()関数を新たに定義し、任意のインデックスの画像を表示できるようにしました。

showNextImage()showPrevImage()は、それぞれ次の画像と前の画像を表示する関数です。

これらの関数を「次へ」「前へ」ボタンのクリックイベントにバインドすることで、ボタン操作でスライドショーをコントロールできるようになりました。

自動再生はsetInterval()で引き続き行われるので、ボタンを操作しない限りは一定間隔で画像が切り替わります。

実行結果

<!-- 3秒ごとに自動再生+「次へ」「前へ」ボタンでの手動操作も可能 -->
<div id="slideshow">
  <img src="image1.jpg" alt="画像1" class="active">
  <img src="image2.jpg" alt="画像2">
  <img src="image3.jpg" alt="画像3">
  <button id="prev">&lt;</button>
  <button id="next">&gt;</button>
</div>

自動再生とボタン操作、両方の利点を兼ね備えたスライドショーになりましたね。

○サンプルコード3:自動再生フェードイン

続いて、自動再生機能に特化したサンプルコードを紹介します。

一定時間ごとに自動的に画像が切り替わるので、手動操作は一切不要です。

コードを見てみましょう。

const slideshow = document.getElementById('slideshow');
const images = slideshow.getElementsByTagName('img');
let currentIndex = 0;

function startSlideshow() {
  images[currentIndex].classList.remove('active');
  currentIndex = (currentIndex + 1) % images.length;
  images[currentIndex].classList.add('active');
  setTimeout(startSlideshow, 3000);
}

startSlideshow();

JavaScriptでは、startSlideshow()関数を再帰的に呼び出すことで、自動再生を実現しています。

setTimeout()を使って一定時間(3000ミリ秒=3秒)後に自分自身を呼び出すことで、無限に画像を切り替え続けます。

この方法だと、自動再生を停止するためのコードが別途必要になりますが、シンプルに自動再生だけを実装したい場合には有効です。

実行結果

<!-- 3秒ごとに無限に自動再生 -->
<div id="slideshow">
  <img src="image1.jpg" alt="画像1" class="active">
  <img src="image2.jpg" alt="画像2">
  <img src="image3.jpg" alt="画像3">
</div>

画像が次々と切り替わり、エンドレスにスライドショーが続きます。

目を引く演出として効果的ですね。

○サンプルコード4:ループ再生フェードイン

最後に、ループ再生機能を追加したフェードインスライドショーのサンプルコードをご紹介します。

これは、最後の画像まで表示したら最初の画像に戻り、繰り返し再生される仕組みです。

コードはこちら。

const slideshow = document.getElementById('slideshow');
const images = slideshow.getElementsByTagName('img');
let currentIndex = 0;
let timer;

function startSlideshow() {
  images[currentIndex].classList.remove('active');
  currentIndex = (currentIndex + 1) % images.length;
  images[currentIndex].classList.add('active');
  timer = setTimeout(startSlideshow, 3000);
}

function stopSlideshow() {
  clearTimeout(timer);
}

slideshow.addEventListener('mouseenter', stopSlideshow);
slideshow.addEventListener('mouseleave', startSlideshow);

startSlideshow();

先ほどの自動再生の例に、ループ再生の仕組みを追加しています。

startSlideshow()関数内で、currentIndeximages.lengthで割った余りを次のインデックスとすることで、最後の画像の次は最初の画像に戻るようにしています。

また、スライドショーの上にマウスカーソルを乗せると一時停止し、カーソルを外すと再生が再開されるような機能も付けました。

mouseentermouseleaveイベントを監視し、clearTimeout()で自動再生を停止・再開させています。

実行結果

<!-- 3秒ごとにループ再生(マウスオーバーで一時停止) -->
<div id="slideshow">
  <img src="image1.jpg" alt="画像1" class="active">
  <img src="image2.jpg" alt="画像2">
  <img src="image3.jpg" alt="画像3">
</div>

アニメーションは滑らかに続き、最後の画像から最初の画像へ自然に移行します。

スライドショー上にマウスカーソルを乗せると、アニメーションが一時停止するのも確認できますね。

●横スクロールスライドショーの実装

フェードインスライドショーに続いて、今度は横スクロールスライドショーの実装方法をマスターしていきましょう。

横スクロールスライドショーは、画像を横方向にスライドさせて切り替える視覚的に印象的なエフェクトです。

Webサイトのヒーローイメージやプロダクトの紹介などに使われることが多く、横長のレイアウトを活かしたダイナミックな演出が可能です。

スマートフォンでは、フリック操作になじみやすいのも魅力ですね。

それでは、シンプルな横スクロールスライドショーの実装から始めていきましょう。

○サンプルコード5:シンプルな横スクロール

<div id="slideshow">
  <div class="slide-container">
    <img src="image1.jpg" alt="画像1">
    <img src="image2.jpg" alt="画像2">
    <img src="image3.jpg" alt="画像3">
  </div>
</div>
#slideshow {
  width: 100%;
  overflow-x: scroll;
  -webkit-overflow-scrolling: touch;
}

.slide-container {
  display: flex;
  width: 300%;
  transition: transform 0.5s ease-in-out;
}

.slide-container img {
  width: 33.33%;
  height: auto;
  object-fit: cover;
}
const slideContainer = document.querySelector('.slide-container');
let currentIndex = 0;

function showNextSlide() {
  currentIndex = (currentIndex + 1) % 3;
  slideContainer.style.transform = `translateX(-${currentIndex * 33.33}%)`;
}

setInterval(showNextSlide, 3000);

コードの説明をしていきますね。

HTMLでは、<div id="slideshow">の中に<div class="slide-container">を配置し、その中に<img>要素を3つ並べています。

CSSでは、#slideshowoverflow-x: scrollを設定することで、横スクロールを有効にしています。

-webkit-overflow-scrolling: touchはiOSのWebビューでネイティブスクロールを有効にするためのプロパティです。

.slide-containerdisplay: flexでFlexboxレイアウトを適用し、width: 300%で画像3枚分の横幅を確保しています。

transitionプロパティでスライド時のアニメーションを指定しています。

.slide-container imgwidth: 33.33%で各画像の横幅を全体の1/3に設定し、object-fit: coverで縦横比を維持したままトリミングしています。

JavaScriptでは、setInterval()を使って3秒ごとにshowNextSlide()関数を呼び出しています。

この関数内で、translateX()を使って.slide-containerの位置をスライドさせることで、画像を切り替えています。

実行結果

<!-- 3秒ごとに画像が横スクロールで切り替わる -->
<div id="slideshow">
  <div class="slide-container">
    <img src="image1.jpg" alt="画像1">
    <img src="image2.jpg" alt="画像2">
    <img src="image3.jpg" alt="画像3">
  </div>
</div>

画像がスムーズに横スクロールしていく様子が確認できましたね。

CSSのtransitionプロパティを使うことで、なめらかなスライドアニメーションを実現しています。

○サンプルコード6:ボタン付き横スクロール

横スクロールスライドショーにも、「次へ」「前へ」ボタンを付けてみましょう。

ユーザーが任意のタイミングで画像を切り替えられるようになります。

サンプルコードはこちらです。

<div id="slideshow">
  <div class="slide-container">
    <img src="image1.jpg" alt="画像1">
    <img src="image2.jpg" alt="画像2">
    <img src="image3.jpg" alt="画像3">
  </div>
  <button id="prev">&lt;</button>
  <button id="next">&gt;</button>
</div>
const slideContainer = document.querySelector('.slide-container');
const prevButton = document.getElementById('prev');
const nextButton = document.getElementById('next');
let currentIndex = 0;

function showSlide(index) {
  currentIndex = (index + 3) % 3;
  slideContainer.style.transform = `translateX(-${currentIndex * 33.33}%)`;
}

function showNextSlide() {
  showSlide(currentIndex + 1);
}

function showPrevSlide() {
  showSlide(currentIndex - 1);
}

prevButton.addEventListener('click', showPrevSlide);
nextButton.addEventListener('click', showNextSlide);

setInterval(showNextSlide, 3000);

HTMLには<button>要素を2つ追加し、CSSでボタンのスタイルを調整しています。

JavaScriptでは、showSlide()関数を定義して、任意のインデックスの画像を表示できるようにしました。

showNextSlide()showPrevSlide()は、それぞれ次の画像と前の画像を表示する関数です。

これらの関数を「次へ」「前へ」ボタンのクリックイベントにバインドすることで、ボタン操作でスライドショーをコントロールできるようになりました。自動再生はsetInterval()で引き続き行われます。

実行結果

<!-- 3秒ごとに自動再生+「次へ」「前へ」ボタンでの手動操作も可能 -->
<div id="slideshow">
  <div class="slide-container">
    <img src="image1.jpg" alt="画像1">
    <img src="image2.jpg" alt="画像2">
    <img src="image3.jpg" alt="画像3">
  </div>
  <button id="prev">&lt;</button>
  <button id="next">&gt;</button>
</div>

ボタンクリックでスライドショーを操作できるようになり、ユーザビリティが向上しましたね。

○サンプルコード7:自動再生横スクロール

横スクロールスライドショーの自動再生版のサンプルコードも用意しました。

一定時間ごとに自動でスライドが切り替わるので、手動操作は不要です。

コードを見ていきましょう。

const slideContainer = document.querySelector('.slide-container');
let currentIndex = 0;

function startSlideshow() {
  currentIndex = (currentIndex + 1) % 3;
  slideContainer.style.transform = `translateX(-${currentIndex * 33.33}%)`;
  setTimeout(startSlideshow, 3000);
}

startSlideshow();

JavaScriptでは、startSlideshow()関数を再帰的に呼び出すことで、自動再生を実現しています。

setTimeout()を使って一定時間(3000ミリ秒=3秒)後に自分自身を呼び出すことで、無限に画像を切り替え続けます。

実行結果

<!-- 3秒ごとに無限に自動再生 -->
<div id="slideshow">
  <div class="slide-container">
    <img src="image1.jpg" alt="画像1">
    <img src="image2.jpg" alt="画像2">
    <img src="image3.jpg" alt="画像3">
  </div>
</div>

シンプルに自動再生だけを実装したい場合は、この方法が有効ですね。

次々と画像が切り替わり、横スクロールスライドショーが延々と続きます。

○サンプルコード8:ループ再生横スクロール

最後に、ループ再生機能を備えた横スクロールスライドショーのサンプルコードを紹介します。

最後の画像まで表示したら最初の画像に戻り、繰り返し再生されます。

コードはこちらです。

const slideContainer = document.querySelector('.slide-container');
let currentIndex = 0;
let timer;

function startSlideshow() {
  currentIndex = (currentIndex + 1) % 3;
  slideContainer.style.transform = `translateX(-${currentIndex * 33.33}%)`;
  timer = setTimeout(startSlideshow, 3000);
}

function stopSlideshow() {
  clearTimeout(timer);
}

slideContainer.addEventListener('mouseenter', stopSlideshow);
slideContainer.addEventListener('mouseleave', startSlideshow);

startSlideshow();

先ほどの自動再生の例に、ループ再生の仕組みを追加しました。

startSlideshow()関数内で、currentIndex3で割った余りを次のインデックスとすることで、最後の画像の次は最初の画像に戻るようにしています。

また、スライドショー上にマウスカーソルを乗せると一時停止し、カーソルを外すと再生が再開されるような機能も付けました。

mouseentermouseleaveイベントを監視し、clearTimeout()で自動再生を停止・再開させています。

実行結果

<!-- 3秒ごとにループ再生(マウスオーバーで一時停止) -->
<div id="slideshow">
  <div class="slide-container">
    <img src="image1.jpg" alt="画像1">
    <img src="image2.jpg" alt="画像2">
    <img src="image3.jpg" alt="画像3">
  </div>
</div>

横スクロールが滑らかに続き、最後の画像から最初の画像へ自然につながっています。

マウスオーバーで一時停止する機能もバッチリ動作していますね。

●よくあるエラーと対処法

JavaScriptでスライドショーを実装する際、思わぬエラーに遭遇することがあります。

初心者の方は特に、どこがおかしいのかわからずに困ってしまうことも多いでしょう。

そこで、スライドショー実装時のよくあるエラーとその対処法について解説していきます。

エラーメッセージをしっかり読み、原因を特定することが大切ですよ。

落ち着いて、一つずつエラーを解決していけば、必ずスライドショーを完成させることができます。

一緒にがんばりましょう!

○画像が表示されない場合

スライドショーを実装したのに、画像が表示されないことがあります。

どうしてだろう?と焦ってしまいますよね。

考えられる原因はいくつかあります。

まず、画像のパスが正しいかどうかを確認しましょう。

HTMLの<img>要素のsrc属性に指定したパスと、実際の画像ファイルの場所が一致していないとエラーになります。

<img src="images/slide1.jpg" alt="スライド1">

この例では、HTMLファイルと同じ階層にimagesフォルダがあり、その中にslide1.jpgという画像ファイルが存在することが前提です。

フォルダ名やファイル名が違う場合は、パスを修正する必要があります。

また、画像ファイルの拡張子が正しいかも確認が必要です。

jpgなのにpngと書いていたりすると、画像は表示されません。

もう一つの可能性は、CSSで画像を非表示にしてしまっているケースです。

display: nonevisibility: hiddenなどのスタイルが適用されていないか、CSSをチェックしてみてください。

img {
  display: none; /* これだと画像が表示されない */
}

この点を確認・修正することで、多くの場合は画像が表示されるようになるはずです。

○スライド切り替えが機能しない場合

スライドショーの実装で次に多いのが、スライド切り替えがうまく機能しないというエラーです。

JavaScriptの記述ミスが原因であることが多いです。

コンソールにエラーメッセージが表示されていないか確認してみましょう。

Uncaught TypeErrorUncaught ReferenceErrorなどのエラーが出ている場合は、JavaScriptのコードを見直す必要があります。

例えば、次のようなエラーメッセージが出ているとします。

Uncaught TypeError: Cannot read property 'classList' of undefined

これは、classListプロパティを持たないオブジェクトに対してclassListを使おうとしたことを表しています。

つまり、querySelector()getElementById()で要素を取得できていない可能性が高いです。

const slide = document.querySelector('.slide');
slide.classList.add('active'); // エラーが発生する行

この例だと、slide変数にnullが入っているため、classListプロパティを読み取ることができずにエラーになります。

セレクターが間違っていないか、該当する要素が存在するかを確認し、修正しましょう。

また、スライドショーのコードを見直して、ロジックが正しいかチェックすることも大切です。

配列の添字が範囲外になっていたり、無限ループになったりしていないか、しっかり確認してくださいね。

○レイアウトが崩れる場合

JavaScriptは問題なく動いているのに、スライドショーのレイアウトが崩れてしまうこともあります。

この場合は、CSSを見直してみましょう。

よくある原因は、画像のサイズが想定と違うことです。

widthheightを指定しているのに、実際の画像サイズと合っていないと、レイアウトが崩れる可能性があります。

img {
  width: 500px;
  height: 300px;
}

この例だと、画像の実際のサイズが500×300ピクセルでない場合、無理やり引き伸ばされたり、余白ができたりしてレイアウトが崩れます。

max-widthmax-heightを使ったり、object-fitプロパティを活用したりすると、画像のアスペクト比を維持しながらレイアウトを整えられます。

img {
  max-width: 100%;
  height: auto;
  object-fit: cover;
}

また、スライドショーのコンテナー要素や、スライドの要素に対して、適切なwidthheightpaddingmarginなどが設定されているか確認しましょう。

これらの値が適切でないと、レイアウトが崩れる原因になります。

.slideshow {
  width: 100%;
  height: 400px;
  overflow: hidden;
}

.slide {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

CSSをしっかりチェックして、レイアウトが崩れないように調整することが大切ですね。

●スライドショーの応用例

さて、ここまでフェードインと横スクロールの2種類のスライドショーを作成してきましたが、JavaScriptの力を借りればもっと自由にカスタマイズできるんです。

色々なアイデアを形にして、オリジナリティあふれるスライドショーを実装してみるのはとってもワクワクしますよね。

少しアレンジを加えるだけで、Webサイトの印象がガラッと変わります。

ぜひ自分なりのこだわりを詰め込んだスライドショーを作ってみてください。

○サンプルコード9:サムネイル付きスライドショー

まずは、サムネイル付きのスライドショーを作ってみましょう。

メインの画像の下に、小さなサムネイル画像を並べて表示します。

サムネイルをクリックすると、対応するメイン画像に切り替わるようにしてみましょう。

サンプルコードを見てみましょう。

<div id="slideshow">
  <img id="main-image" src="image1.jpg" alt="メイン画像">
  <div id="thumbnails">
    <img src="image1.jpg" alt="サムネイル1" class="thumbnail active">
    <img src="image2.jpg" alt="サムネイル2" class="thumbnail">
    <img src="image3.jpg" alt="サムネイル3" class="thumbnail">
  </div>
</div>
#slideshow {
  width: 100%;
  text-align: center;
}

#main-image {
  max-width: 100%;
  height: auto;
}

#thumbnails {
  margin-top: 10px;
}

.thumbnail {
  width: 80px;
  height: 80px;
  object-fit: cover;
  margin: 0 5px;
  border: 2px solid transparent;
  cursor: pointer;
}

.thumbnail.active {
  border-color: #333;
}
const mainImage = document.getElementById('main-image');
const thumbnails = document.querySelectorAll('.thumbnail');

thumbnails.forEach((thumbnail, index) => {
  thumbnail.addEventListener('click', () => {
    mainImage.src = `image${index + 1}.jpg`;
    thumbnails.forEach(thumbnail => thumbnail.classList.remove('active'));
    thumbnail.classList.add('active');
  });
});

コードの説明をしていきますね。

HTMLでは、id="main-image"を持つ<img>要素を配置し、その下にid="thumbnails"<div>要素内にサムネイル用の<img>要素を3つ並べています。

CSSでは、メイン画像を中央に配置し、サムネイルは横並びにしています。

.thumbnailにはクリックできるようにカーソルのスタイルを指定し、.activeクラスが付いている場合は枠線を表示するようにしています。

JavaScriptでは、全てのサムネイルに対してクリックイベントを設定しています。

クリックされたサムネイルに対応するメイン画像を表示し、.activeクラスを付け替えることで、現在選択中のサムネイルが分かるようにしています。

実行結果

<div id="slideshow">
  <img id="main-image" src="image1.jpg" alt="メイン画像">
  <div id="thumbnails">
    <img src="image1.jpg" alt="サムネイル1" class="thumbnail active">
    <img src="image2.jpg" alt="サムネイル2" class="thumbnail">
    <img src="image3.jpg" alt="サムネイル3" class="thumbnail">
  </div>
</div>

サムネイルをクリックすると、メイン画像が切り替わり、選択中のサムネイルに枠線が表示されます。

直感的な操作でスライドショーを閲覧できますね。

○サンプルコード10:複数のスライドショーを同期

複数のスライドショーを同期させて、まるで1つのスライドショーのように動かしてみるのもおもしろいアイデアです。

異なるスライドショーの切り替えタイミングを揃えることで、統一感のある演出ができます。

サンプルコードを確認しましょう。

<div id="slideshow1" class="slideshow">
  <img src="image1.jpg" alt="スライドショー1の画像1">
  <img src="image2.jpg" alt="スライドショー1の画像2">
  <img src="image3.jpg" alt="スライドショー1の画像3">
</div>

<div id="slideshow2" class="slideshow">
  <img src="image4.jpg" alt="スライドショー2の画像1">
  <img src="image5.jpg" alt="スライドショー2の画像2">
  <img src="image6.jpg" alt="スライドショー2の画像3">
</div>
const slideshows = document.querySelectorAll('.slideshow');

function showNextSlide() {
  slideshows.forEach(slideshow => {
    const images = slideshow.querySelectorAll('img');
    const currentImage = slideshow.querySelector('img.active');
    const nextImage = currentImage.nextElementSibling || images[0];

    currentImage.classList.remove('active');
    nextImage.classList.add('active');
  });
}

setInterval(showNextSlide, 3000);

HTMLでは、class="slideshow"を持つ<div>要素を2つ用意し、それぞれに3枚ずつ画像を配置しています。

JavaScriptでは、.slideshow要素を全て取得し、showNextSlide()関数内で、各スライドショーの現在表示中の画像を取得して、次の画像に切り替えています。

nextElementSiblingプロパティを使って次の画像を取得し、なければ最初の画像に戻るようにしています。

setInterval()を使って、3秒ごとにshowNextSlide()関数を呼び出すことで、全てのスライドショーが同期して切り替わるようにしています。

実行結果

<div id="slideshow1" class="slideshow">
  <img src="image1.jpg" alt="スライドショー1の画像1" class="active">
  <img src="image2.jpg" alt="スライドショー1の画像2">
  <img src="image3.jpg" alt="スライドショー1の画像3">
</div>

<div id="slideshow2" class="slideshow">
  <img src="image4.jpg" alt="スライドショー2の画像1" class="active">
  <img src="image5.jpg" alt="スライドショー2の画像2">
  <img src="image6.jpg" alt="スライドショー2の画像3">
</div>

2つのスライドショーが同時に切り替わり、まるで1つのスライドショーのように動作しています。

複数のスライドショーを連動させることで、より印象的な演出が可能になりますね。

○サンプルコード11:スライドショーにキャプションを追加

スライドショーに画像の説明文(キャプション)を付けると、情報量が増えてよりわかりやすく伝えられます。

スライドが切り替わるタイミングでキャプションも一緒にアニメーションさせると、洗練された印象になりますよ。

サンプルコードを見ていきましょう。

<div id="slideshow">
  <div class="slide">
    <img src="image1.jpg" alt="画像1">
    <p class="caption">キャプション1</p>
  </div>
  <div class="slide">
    <img src="image2.jpg" alt="画像2">
    <p class="caption">キャプション2</p>
  </div>
  <div class="slide">
    <img src="image3.jpg" alt="画像3">
    <p class="caption">キャプション3</p>
  </div>
</div>
#slideshow {
  position: relative;
  width: 100%;
  height: 400px;
}

.slide {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 1s;
}

.slide.active {
  opacity: 1;
}

.caption {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  padding: 10px;
  background-color: rgba(0, 0, 0, 0.7);
  color: #fff;
  opacity: 0;
  transition: opacity 1s;
}

.slide.active .caption {
  opacity: 1;
}
const slides = document.querySelectorAll('.slide');
let currentIndex = 0;

function showNextSlide() {
  slides[currentIndex].classList.remove('active');
  currentIndex = (currentIndex + 1) % slides.length;
  slides[currentIndex].classList.add('active');
}

setInterval(showNextSlide, 3000);

HTMLでは、<div class="slide">の中に<img>要素とキャプション用の<p class="caption">要素を配置しています。

CSSでは、.slide.captionposition: absoluteで重ねて配置し、opacityを使って非表示にしています。

.activeクラスが付いている場合にopacityを1にすることで、画像とキャプションを表示するようにしています。

transitionプロパティでフェードイン・フェードアウトのアニメーションを指定しています。

JavaScriptは、先ほどのサンプルコードとほぼ同じですね。

.slide要素を取得して、一定時間ごとにactiveクラスを付け替えています。

実行結果を確認しましょう。

<div id="slideshow">
  <div class="slide active">
    <img src="image1.jpg" alt="画像1">
    <p class="caption">キャプション1</p>
  </div>
  <div class="slide">
    <img src="image2.jpg" alt="画像2">
    <p class="caption">キャプション2</p>
  </div>
  <div class="slide">
    <img src="image3.jpg" alt="画像3">
    <p class="caption">キャプション3</p>
  </div>
</div>

画像が切り替わるタイミングでキャプションもフェードイン・フェードアウトし、スライドショーに説明文が追加されました。

画像だけでは伝えきれない情報をテキストで補足することで、よりわかりやすいスライドショーになります。

○サンプルコード12:レスポンシブ対応スライドショー

最後に、レスポンシブ対応のスライドショーを作ってみましょう。

スマートフォンやタブレットなど、様々なデバイスで見やすく表示されるように調整します。

サンプルコードはこちらです。

<div id="slideshow">
  <img src="image1.jpg" alt="画像1">
  <img src="image2.jpg" alt="画像2">
  <img src="image3.jpg" alt="画像3">
</div>
#slideshow {
  position: relative;
  width: 100%;
  padding-top: 56.25%; /* 16:9の縦横比 */
}

#slideshow img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 1s;
}

#slideshow img.active {
  opacity: 1;
}

@media screen and (max-width: 600px) {
  #slideshow {
    padding-top: 75%; /* 4:3の縦横比 */
  }
}
const images = document.querySelectorAll('#slideshow img');
let currentIndex = 0;

function showNextSlide() {
  images[currentIndex].classList.remove('active');
  currentIndex = (currentIndex + 1) % images.length;
  images[currentIndex].classList.add('active');
}

setInterval(showNextSlide, 3000);

HTMLは特に変更ありません。<img>要素を#slideshowの中に配置しているだけですね。

CSSでは、#slideshowpadding-topを指定することで、縦横比を固定しています。ここでは16:9の縦横比を設定しています。

position: absoluteを使って画像を重ねて配置し、object-fit: coverで縦横比を維持したまま画像を拡大・トリミングしています。

@mediaクエリを使って、画面幅が600px以下の場合にpadding-topの値を変更し、縦横比を4:3に切り替えています。

これにより、スマートフォンなどの小さな画面でも見やすくなります。

JavaScriptは、これまでのサンプルコードと同じですね。

#slideshow内の<img>要素を取得して、一定時間ごとにactiveクラスを付け替えています。

実行結果を見てみましょう。

<div id="slideshow">
  <img src="image1.jpg" alt="画像1" class="active">
  <img src="image2.jpg" alt="画像2">
  <img src="image3.jpg" alt="画像3">
</div>

画面サイズに応じて、スライドショーの縦横比が切り替わります。

PC画面では16:9、スマートフォンでは4:3の縦横比で表示されるので、どのデバイスでも見やすいスライドショーになりました。

まとめ

JavaScriptを使ったスライドショーの実装方法について、フェードインと横スクロールの2種類を中心に解説してきました。

基本的な実装からボタン操作、自動再生、ループ再生など、様々なバリエーションのサンプルコードを紹介し、実践的なスキルが身につくようにわかりやすく説明してきたつもりです。

本記事で紹介した内容を手がかりに、ぜひ自分だけのオリジナルのスライドショーを作ってみてください。

最初はうまくいかないこともあるかもしれませんが、エラーメッセージを頼りにデバッグを繰り返していけば、必ず完成させることができるはずです。