[ プログラミング ] jQueryでテキストメニュー付きのスライドショーを作る方法

サッカー協会のWebサイトのようなスライドショーを作ってみたいと思います。

スライドタイプのデモはこちらから。

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 type = 'slide'; // 'slide' or'fade'

    // サブコンテンツに<ul>タグを追加
    $sub.append('<ul></ul>');

    // キャプションを表示
    var mainLength = $main.find('li').length;
    for(var i = 0 ; i < mainLength ; i++){
        var altText = $main.find('img').eq(i).attr('alt');
        var link = $main.find('a').eq(i).attr('href');
        $main.find('li').eq(i).append('<span>' + altText + '</span>');
        $sub.find('ul').append('<li><a href="' + link + '">' + altText + '</a></li>');
        // 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」クラスの追加・削除
        if(type == 'fade') {
            $active.fadeOut(speed).removeClass('active');
            $next.fadeIn(speed).addClass('active');
        }

        // スライドおよび「.active」クラスの追加・削除
        if(type == 'slide') {
            var elementWidth = $main.find('li').width();
            $active.css({'left': 0 +'px' , 'display' : 'block'});
            $next.css({'left': elementWidth +'px' , 'display' : 'block'});
            $active.not(':animated').animate({'left': '-=' + elementWidth +'px'}, speed).removeClass('active');
            $next.not(':animated').animate({'left': '-=' + elementWidth +'px'}, 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().css({'left': 0 +'px'});
            // サムネイルに「.active」クラスを追加・削除
            $sub.find('li').removeClass('active');
            $(this).addClass('active');
            // タイマーストップ
            stopTimer();
        },
        function () {
            return false;
        }
    );

    $sub.find('li a').each(function() {
        var $target = $(this);
        if($target.height() > $sub.find('li').height()){
            // オリジナルの文章を取得
            var html = $target.html();

            // オリジナルの文章を複製
            var $clone = $target.clone();
            $clone.css({
                display: 'none',
                position : 'absolute',
                overflow : 'visible'
            })
            .width($target.width())
            .height('auto');

            // 複製した文章を追加
            $target.after($clone);

            // 指定した高さになるまで、1文字ずつ消去していく
            while((html.length > 0) && ($clone.height() > $sub.find('li').outerHeight())) {
                html = html.substr(0, html.length - 1);
                $clone.html(html + '…');
            }

            // 文章を入れ替えて、複製した要素を削除
            $target.html($clone.html());
            $clone.remove();
        }

        // 文章整形
        $target.css({'display' : 'block'});
        var height= $target.height();
        var parentHeight= $target.parent('li').height();
        var position= Math.floor((parentHeight - height) / 2);
        $target.css({'padding-top' : position});
    });
});
</script>
<style>
.wrap {
    overflow:hidden;
    width:910px;
    margin:30px auto;
}

#slide_main ul {
    overflow:hidden;
    position:relative;
    float:left;
    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;
    float:right;
    margin:0;
    padding:0;
    list-style:none;
}

#slide_sub h2 {
    margin:0 0 5px 0;
    padding:5px;
    font-size:20px;
    color:#fff;
    background:#000;
}

#slide_sub ul {
    margin:0;
    padding:0;
}

#slide_sub li {
    box-sizing:border-box;
    width:300px;
    height:56px;
    margin:0 0 5px 0;
    padding:5px;
    font-size:14px;
    line-height:1.6;
    border:1px solid #999;
    cursor:pointer;
    list-style:none;
}

#slide_sub li.active {
    background:#ddd;
}
</style>
<title>jQueryでテキストメニュー付きのスライドショーを作る</title>
</head>
<body>
<div class="wrap">
    <div id="slide_main">
        <ul>
            <li><a href="index.html"><img src="images/photo01.jpg" alt="ここに表示されているのはalt属性の値です。"></a></li>
            <li><a href="index.html"><img src="images/photo02.jpg" alt="長い文章を書くと、以下のようにテキストが途中で切れて末尾に三点リーダーが付きます。"></a></li>
            <li><a href="index.html"><img src="images/photo03.jpg" alt="あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん"></a></li>
            <li><a href="index.html"><img src="images/photo04.jpg" alt="あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをんあいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん"></a></li>
            <li><a href="index.html"><img src="images/photo05.jpg" alt="あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん"></a></li>
            <li><a href="index.html"><img src="images/photo06.jpg" alt="あいうえおかきくけこ"></a></li>
        </ul>
    </div><!-- /#slide_main -->
    <div id="slide_sub">
        <h2>トピックス</h2>
    </div><!-- /#slide_sub -->
</div><!-- /.wrap -->
</body>
</html>

サッカー協会のWebサイトのソースコードを参考にしているわけではないので、動作が違うところもあります。

スライドショーのタイプをスライドタイプにしたい場合は、14行目の「type」の値を「slide」に、フェードタイプにしたい場合は、「fade」にしてください。

各文章は画像のalt属性の値を表示しています。

極力、どんな長さのテキストにも対応するように、テキストメニューの整形には気を付けていますが、100文字程度が綺麗に見える限界ですね。

テキストメニューの高さを固定して、テキストを中央に配置するようにしています。

テキストの高さがメニューより高い場合は、テキストを省略して末尾に「…」を入れるようにしているます。このスクリプトは以下のサイトを参考にしました。ありがとうございます。