さあ、プログラミングを学ぼう

プログラミングに関する知識と経験集

javascriptで作るスライドショー

javascriptを使ってスライドショーを作るぞ!!
完成形はこれだ!!


簡単に説明するぞ。

HTML

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="utf-8">
</head>

<body>
    <div class="container">
        <main>
            <img>
        </main>

        <nav>
            <ul>
                <li id="play">Play</li>
                <li id="pause" class="hidden">Pause</li>
                <li id="prev">&lt;</li>
                <li id="next">&gt;</li>
            </ul>
        </nav>

        <ul class="thumbnails"></ul>
    </div>
</body>

</html>

※codepenで表現したから書かなかったけど、このまま使うとcssとjsファイルの読み込みができないから追記しておいて!

画像を表示させる領域を作るぞ。領域はタグ名でもいいし、クラス名でもいいしid名でもいいから一意になるようにしておけ。でないと予期せぬところまでjsの影響が出てしまう。無難なのはidな。これなら1ページで1つしかないから必ず、思ったところにしかjsの影響が出ない。今回はボリュームも大したことないし、タグで一意にできるから一意のタグ振って終わり。

再生ボタンで自動切り替え、nextボタンで次に行って、prevボタンで前に戻るようにしたいからid振ってボタンの領域も作っておく。

サムネイルの領域も追加しとく。今回はクラス名でいいや。

コードの量が多かったり多くなるならjsをかける対象はidに絞る方がいいぞ!!
最初の方でimgタグにアニメーションかけるぞみたいなことした場合、今後アニメーションいらないけどimgタグ使いたいって時に困る。アニメーション無効化jsとかcssかけなきゃいけなくなる。めんどい。

CSS

ご自由にどうぞ!

javascript

{
    const images = [
        'https://unsplash.it/680/450?image=10',
        'https://unsplash.it/680/450?image=20',
        'https://unsplash.it/680/450?image=30',
        'https://unsplash.it/680/450?image=40',
        'https://unsplash.it/680/450?image=50',
        'https://unsplash.it/680/450?image=60',
        'https://unsplash.it/680/450?image=70',
        'https://unsplash.it/680/450?image=80',
    ];

こうやってスライドショーに使う画像を配列にひとまとめにしておく。インデックスを利用したいからキー名はいらないよ。

    let currentNum = 0;

    function setMainImage(image) {
        document.querySelector('main img').src = image;
    }

    setMainImage(images[currentNum]);

mainタグ内imgタグのsrc属性を切り替える手法を使って画像を取り替えていく。
今はまだ、currentNumは0でしかないからimages[currentNum]は配列の中の一つ目、
'https://unsplash.it/680/450?image=10'に固定であって

<main>
   <img src="https://unsplash.it/680/450?image=10">
</main>

こういう風にしかならないけど、currentNumの数が変われば表示できる画像が変えられるところが味噌。
images[1]だったら2番目の画像になるでしょ。

    function removeCurrentClass() {
        document.querySelectorAll('.thumbnails li')[currentNum]
            .classList.remove('current');
    }

    function addCurrentClass() {
        document.querySelectorAll('.thumbnails li')[currentNum]
            .classList.add('current');
    }

これはまあ、currentっていうクラスを着けたり取ったりして選択されているサムネイルとそれ以外で見た目変えるためのやつ。

    const thumbnails = document.querySelector('.thumbnails');

これでとりあえず、thumbnailsクラスの要素にアクセスできて

    images.forEach((image, index) => {
        const li = document.createElement('li');
        if (index === currentNum) {
            li.classList.add('current');
        }

        li.addEventListener('click', () => {
            setMainImage(image);
            removeCurrentClass();
            currentNum = index;
            addCurrentClass();
        });

        const img = document.createElement('img');
        img.src = image;
        li.appendChild(img);
        thumbnails.appendChild(li);
    });

imagesって配列に入れてある画像のurlの数だけ処理を回すんだけど、
サムネイルを一つずつli要素で表現したいから、li要素を作ってそれを定数に格納。
で、index(順番)とcurrentNum(表示させるって決まった画像番号)が一致したらば、その時のli要素にcurrentクラスを付けとくぞと。
クリックされたらそのサムネイルに使ってる画像を表示させて、currentクラスを一旦全ての要素から外し、クリックされたサムネイルの画像の順番(index)をcurrentNumに入れて、該当するli要素にcurrentクラスをつけるっていうクリックイベントを作る。
それでimgっていう定数にimgタグを格納してそれのsrc属性にimagesに入っている画像urlを一つ付けてあげてthumbnailsクラスの要素の中に配置する。
これをimagesに入っている画像urlの一つ目から順番にやっていくと。

    const next = document.getElementById('next');
    next.addEventListener('click', () => {
        removeCurrentClass();
        currentNum++;
        if (currentNum === images.length) {
            currentNum = 0;
        }
        addCurrentClass();
        setMainImage(images[currentNum]);
    });

    const prev = document.getElementById('prev');
    prev.addEventListener('click', () => {
        removeCurrentClass();
        currentNum--;
        if (currentNum < 0) {
            currentNum = images.length - 1;
        }
        addCurrentClass();
        setMainImage(images[currentNum]);
    });

    let timeoutId;

    function playSlideshow() {
        timeoutId = setTimeout(() => {
            next.click();
            playSlideshow();
        }, 1000);
    }

    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', () => {
        play.classList.remove('hidden');
        pause.classList.add('hidden');
        clearTimeout(timeoutId);
    });
}

あとはボタン押してcurrentNum変えて、変えたらそのcurrentNumに該当する画像を表示させようぜという処理を追加して終わり。
これがスライドショーの基礎だな。これができれば、css次第でどれだけでもかっこよくできるぞ。頑張れ!