[ プログラミング ] シンプルなサムネイル付きスライドショーをjQueryで作る

スライドショーは色々と作ってきているのですが、意外にもサムネイル付きのスライドショーを作ったことがなかったので作ってみました。

スライドショーは付けようと思えば、色んな機能を付けれるのですが、今回は、フェードするタイプで、ホバーすると大きな画像を表示するようにしました。あと、サムネイルにマウスアウトした際に、スライドショーが止まるタイプと、スライドショーが継続するタイプの2つを考えてみました。

スライドショーが継続するタイプのデモはこちらから。

DOMO

スライドショーが止まるタイプのデモはこちらから。

DOMO

HTML5でコーティングしています。jQueryもCSSもHTMLのheadタグ内に書いています。

HTML

<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<script src='js/jquery.js'></script>
<script>
    $(function(){
    var $main = $('#slide_main ul');
    var $sub = $('#slide_sub');
    var speed = 3000;
    var interval = 5000;
    var num = 0;
    var sub_num = 0;
    var oparation = 'stop'; // 'repeat' or'stop'

    // キャプションを表示
    var mainLength = $main.find('li').length;
    for(var i = 0 ; i < mainLength ; i++){
        var altText = $main.find('img').eq(i).attr('alt');
        $main.find('li').eq(i).append('<span>' + altText + '</span>');
        // alt属性が空の場合は、「padding:0」を指定
        if(altText.length == 0) {
            $main.find('span').eq(i).css({'padding' : '0'});
        }
    }

    // 写真を非表示
    $main.find('li').hide();
    // 最初の写真を表示して、「.active」クラスを追加
    $main.find('li:first').addClass('active').show();
    // サムネイルに「.active」クラスを追加
    $sub.find('li:first').addClass('active');

    // 自動切り替えスタート
    var start;
    var startTimer = function () {
        start = setInterval(function(){change();},interval);
    };

    // 自動切り替えストップ
    var stopTimer = function () {
         clearInterval(start);
    };

    // スライドショースタート
    startTimer();

    // スライドショー
    var change = function(){
        // 現在の写真と次の写真を取得
        var $active = $main.find('li.active');
        var $next = $active.next('li').length?$active.next('li'):$main.find('li:first');

        // フェードおよび「.active」クラスの追加・削除
        $active.fadeOut(speed).removeClass('active');
        $next.fadeIn(speed).addClass('active');

        // 「.active」クラスが付いているli要素の番号を取得
        num = $main.find('li.active').index();

        // サムネイルに「.active」クラスを追加・削除
        $sub.find('li').eq(num).addClass('active');
        $sub.find('li').eq(num - 1).removeClass('active');
    }

// サムネイルにホバーした時の処理
    $sub.find('li').hover(
        function () {
            // ホバーした写真の番号を取得
            var sub_num = $(this).index();
            // ホバーした写真を表示
            $main.find('li').hide();
            $main.find('li').eq(sub_num).show();
            // サムネイルに「.active」クラスを追加・削除
            $sub.find('li').removeClass('active');
            $(this).addClass('active');
            // タイマーストップ
            stopTimer();
        },
        function () {
            if(oparation == 'stop'){
                return false;
            }
            if(oparation == 'repeat'){
                // スライドショー用の画像を表示
                $main.find('li').hide();
                $main.find('li').eq(num).show();
                // サムネイルに「.active」クラスを追加・削除
                $(this).removeClass('active');
                $sub.find('li').eq(num).addClass('active');
                // タイマースタート
                startTimer();
            }
        }
    );
});
</script><style>
.wrap {
    overflow:hidden;
    width:600px;
    margin:30px auto;
}

#slide_main {
    position:relative;
    margin:0;
    padding:0;
    width:600px;
    height:400px;
}

#slide_main li {
    list-style:none;
    position:absolute;
    top:0;
    left:0;
}

#slide_main img {
    width:600px;
    vertical-align:bottom;
}

#slide_main span {
    box-sizing:border-box;
    width:100%;
    display:block;
    position:absolute;
    left:0;
    bottom:0;
    padding:10px;
    color:#fff;
    background-color: rgba(0, 0, 0, 0.6);
}

#slide_sub {
    position:relative;
    margin:0 -5px;
    padding:0;
}

#slide_sub li {
    list-style:none;
    float:left;
    width:100px;
    margin:5px;
    padding:5px;
    border:1px solid #999;
    cursor:pointer;
}

#slide_sub img {
    width:100px;
    vertical-align:bottom;
}

#slide_sub li.active {
    background:#ddd;
}

</style>
<title>シンプルなサムネイル付きスライドショーをjQueryで作る</title>
</head>
<body>
<div class="wrap">
<div id="slide_main">
    <ul>
        <li><img src="images/photo01.jpg" alt="サムネイル1枚目。にゃんにゃんにゃん、2月22日は猫の日です。"></li>
        <li><img src="images/photo02.jpg" alt="サムネイル2枚目。次の画像はalt属性が空です。"></li>
        <li><img src="images/photo03.jpg" alt=""></li>
        <li><img src="images/photo04.jpg" alt="サムネイル4枚目。にゃんにゃんにゃん、2月22日は猫の日です。"></li>
        <li><img src="images/photo05.jpg" alt="サムネイル5枚目。にゃんにゃんにゃんにゃんにゃんにゃんにゃんにゃんにゃんにゃんにゃん、2月22日は猫の日です。"></li>
    </ul>
</div>
    <ul id="slide_sub">
        <li><img src="images/photo01.jpg" alt=""></li>
        <li><img src="images/photo02.jpg" alt=""></li>
        <li><img src="images/photo03.jpg" alt=""></li>
        <li><img src="images/photo04.jpg" alt=""></li>
        <li><img src="images/photo05.jpg" alt=""></li>
    </ul>
</div>
</body>
</html>

どちらのタイプも同じファイルです。違いといえば、13行目の「oparation」の値がが「’repeat’」か「’stop’」の違いです。

メインの画像のalt属性をキャプション(見出し)として表示しています。内容が空の場合は、CSSで指定しているpadding分背景が表示されてしまいますので、paddingを0にしています。どのようにキャプションを追加するか悩んだのですが、画像のliタグにspanタグを追加してその中にalt属性の値を入れることで、うまく画像と一緒に表示することができました。

スライドショーを動かすのは「setInterval()」、スライドショーを一旦停止するのは「clearInterval()」を使います。

あと、表示されている画像およびサムネイルに「.active」という名前のクラス名を付けるようにしています。これで、動的なデザインができると思います。

22行目と55行目、「.length」は要素の数を返すものですが、それで、要素の存在がわかるのが面白いですね。

今回、初めて知った、というかずっと勘違いしてたのですが、「$sub.find(‘li’).eq(num – 1).removeClass(‘active’);」というように記述していますが、「.eq()」の返り値が「-1」だった場合は、一番最後の要素にマッチするのですね。これはすごい便利です。