ヒビノログ

個人的なメモを淡々と記録していくブログ。最近はLaravelやスマートフォンの話題など。

複数のコンテンツ項目を自動的にスライド表示する

たとえば、Twitterのタイムラインを自分のブログなどに表示するとき、Twitterから公式に提供されているウィジェットを使えばほぼ問題無いのだけど、表示する発言に何らかのフィルタをかける等、TwitterAPIを使って処理した結果を、動きを付けてスライド表示させたい、という場合。

こちらのサイトで紹介されているように、「Simple jQuery Spy Effect」というJSがあるので、基本的にはこれを使うとよいです。

ただ、このスクリプトにはちょっと難点があって、1つの項目を表示する欄の高さが一定になっています。基準となるのは、先頭の項目の表示高さです。 Twitterのつぶやきの長さは一定ではないので、表示に必要な高さも一定ではないのですが、スクリプトをそのまま使うと、2つめ以降の表示が途中で切れたり、余白ができたりしてちょっとカッコ悪いです。

ということで、ちょっと修正して、欄の高さを可変にしてみました。

表示サンプル

JavaScriptサンプル [js]$(function () {
$('ul.twitter').simpleSpy();
});
(function ($) {
$.fn.simpleSpy = function (limit, interval) {
limit = limit || 5; interval = interval || 5000;
return this.each(function () {
// 1. setup
// capture a cache of all the list items
// chomp the list down to limit li elements
var $list = $(this),
$list2 = $('ul.twitter-dummy'), items = [], // uninitialised
currentItem = limit, total = 0, // initialise later on height = '300px'; // capture the cache
$list.find('> li').each(function () {
items.push("<li class='update clear clearfix'>" + $(this).html() + "</li>");
});
total = items.length;
$list.find('> li').filter(':gt(' + (limit - 1) + ')').remove();
// 2. effect
function spy() {
// insert a new item with opacity and height of zero
var $insert = $(items[currentItem]).css({
height : 0,
opacity : 0,
display : 'none'
}).prependTo($list);

        // get real height
        var $insert2 = $(items[currentItem]).css({   
            opacity : 0,   
            display : 'none'  
        }).prependTo($list2);   
        height = $list2.find('&gt; li:first').height();

        // fade the LAST item out   
        $list.find('&gt; li:last').animate({ opacity : 0}, 1000, function () {   
            // increase the height of the NEW first item   
            $insert.animate({ height : height }, 1000).animate({ opacity : 1 }, 1000);   
            // AND at the same time - decrease the height of the LAST item   
            // $(this).animate({ height : 0 }, 1000, function () {   
                // finally fade the first item in (and we can remove the last)   
                $(this).remove();   
            // });   
        });   
        currentItem++;   
        if (currentItem &gt;= total) {   
            return;
        }   
        setTimeout(spy, interval)   
    }   
    spy();   
});   

};
})(jQuery);[/js]

HTMLサンプル [html]<ul class="twitter"> <li class='update clear clearfix'>つぶやきつぶやき</li> <li class='update clear clearfix'>つぶやきつぶやき</li> <li class='update clear clearfix'>つぶやきつぶやき</li> <li class='update clear clearfix'>つぶやきつぶやき</li> <li class='update clear clearfix'>つぶやきつぶやき</li> </ul> <ul class='twitter-dummy'></ul>[/html]

概要としては以下の通り。

  1. 表示に必要な高さを得るために、表示場所と同じスタイルが適用されるulオブジェクトをもう1つ作ります(サンプルでは「twitter-dummy」というのを作ってます)[HTMLサンプル8行目]
  2. そのオブジェクトに対してアイテムを追加します[JavaScriptサンプル34行目~]
  3. ダミーのオブジェクトはheightを指定しないようにして、表示に必要な高さを取得します[JavaScriptサンプル38行目]
  4. その高さを、本来の表示場所の表示高さに指定します[JavaScriptサンプル43行目]
そうするとキレイにできますよ、と。