一定時間で自動的に消える New マークを付ける JavaScript の jQuery 版

小粋空間さんのところで紹介されている「新着エントリーのあるカテゴリーに New マークをつける」の jQuery 版を作ってみました。

このブログの「 Recent Entries 」(最近のブログ記事)のところにある星マーク(New マークのこと)がそれで(下図参照)、3日以内に作成されたブログ記事に表示されるようにしています。

newmark01.jpg

このテクニックは、荒木さんご自身の著書『 Movable Type 4.2 パーフェクトガイド』の中でも紹介されていますし(573ページの「6.39 新着表示」)、WWW WATCHさんらの共著本『 Movable Type 4.x 本格的CMSサイトを構築するためのMTスーパーテクニック クリエイターが身につけておくべき新・100の法則。』でも紹介されていました(146ページの「法則65 一定時間で自動的に消える New マークを付ける」)。

この JavaScript で New マークを表示するロジックは以下のようになっています。

  1. New マークを表示したい場所に、span 要素で記事の更新日時を決まったフォーマットで追加し、CSS で非表示にしておく。
  2. JavaScript でその更新日時と現在日時を比較し、設定された時間以内であれば、その更新日時の span 要素の内容を New マークに書き換え表示する。

企業サイトや情報サイト系では重宝される素敵な機能だと思いますが、この方法だと、New マークを表示するために余計な span 要素を追加しなければなりませんし、JavaScript と CSS を無効にした環境だと、「2008:09:25:06:10:11」といった数字の羅列が表示されてしまいます。

今回カスタマイズした jQuery 版では、それらのデメリットは解消されています。具体的なロジックは以下のとおりです。

  1. New マークを表示したい新着情報の個別記事へのリンクの a 要素に、class="newmarkList" を設定し、 title 属性に次のようなフォーマットで更新日時を追加する。
    2008年09月25日 06時10分11秒 に作成 (メインカテゴリー名)
  2. JavaScript で上記のフォーマットの更新日時を次のように置換する。
    2008:09:25:06:10:11
  3. その更新日時と現在日時を比較し、設定された時間以内であれば、その a 要素の直後に New マークを表示する要素を追加する。

newmark02.jpg

解説

完成したソースコードは次のようになります。

$(document).ready(function(){
    var currentDate = new Date();
    $('.newmarkList').each(function(){
        var pass       // passage time
             = 72;
        var content    // display content
             = '<img class="newmark" src="/img/icon/newmark.gif" alt="3日以内の新着ブログ記事" width="15" height="15" title="3日以内の新着ブログ記事"/>';
        var newmarkAttr = $(this).attr('title');
        newmarkAttr = newmarkAttr.replace(/年|月|日|時|分/g,':');
        newmarkAttr = newmarkAttr.replace(/\s|秒.*/g,'');
        var time = newmarkAttr.split(":");
        var entryDate = new Date(time[0], time[1]-1, time[2], time[3], time[4], time[5]);
        var now = (currentDate.getTime() - entryDate.getTime())/(60*60*1000); 
        now = Math.ceil(now);
        if(now <= pass){
            $(this).after(content);
        }
    });
});

順に解説していきます。

2 行目で現在時刻を取得します。

    var currentDate = new Date();

3 行目で class="newmarkList" をもつ 要素を取得します。

    $('.newmarkList').each(function(){

4 ~ 7 行目で、更新日時から何時間経過するまで New マークを表示するか、New マークとして表示する画像やテキストを設定します。img 要素の内容は適宜変更してください。

        var pass       // passage time
             = 72;
        var content    // display content
             = '<img class="newmark" src="/img/icon/newmark.gif" alt="3日以内の新着ブログ記事" width="15" height="15" title="3日以内の新着ブログ記事"/>';

また、今回の例では画像を使っていますが、テキストにすることも可能です。テキストにする場合は、次のように表示するテキストを span 要素で囲っておいた方が何かと便利です。

        var pass       // passage time
             = 72;
        var content    // display content
             = '<span class="newmark">New !!</span>';

次に、9,10 行目で title 属性の値を取得し、「年」などの区切り文字を「 : 」に置換します。

        newmarkAttr = newmarkAttr.replace(/年|月|日|時|分/g,':');
        newmarkAttr = newmarkAttr.replace(/\s|秒.*/g,'');

なお、今回のサンプルではフォーマットを「2008年09月25日 06時10分11秒 に作成 (メインカテゴリー名)」としましたが、ここの置換によって、JavaScript 上では「秒」以降の文字はすべて削除しますので、「秒」以降は自由に書き換えられます。

  • (例) 2008年09月25日 06時10分11秒 に更新された「ブログ記事タイトル」を読む

11,12 行目で、先ほど置換した title 属性の値を「 : 」ごとに分割し、変数 entryDate にブログ記事更新日時として設定します。

        var time = newmarkAttr.split(":");
        var entryDate = new Date(time[0], time[1]-1, time[2], time[3], time[4], time[5]);

13,14 行目で、現在日時( currentDate )とブログ記事更新日時( entryDate )の差を、時間単位で変数 now に代入します。getTime() は、1970 年 1 月 1 日午前 0 時から現在までの経過をミリ秒単位で取得するので、(60*60*1000) で割ることで「時間」単位にしています。Math.ceil(now) で小数点以下を切り上げます。

        var now = (currentDate.getTime() - entryDate.getTime())/(60*60*1000);
        now = Math.ceil(now);

15 ~ 17 行目で変数 now が、設定した時間( pass )以下の場合に、a 要素の直後に設定した New マーク( content )を追加します。

        if(now <= pass){
            $(this).after(content);
        }

使い方

準備

先ほどのソース全文をコピーして、newmark_jquery.js などのファイル名で保存し、サーバーにアップします。Movable Type や WordPress のように、サイトが UTF-8 の場合は js ファイルの文字コードも UTF-8 で保存してください。

head 要素内で以下のようにしてファイルを読み込みます。src 属性内は適宜変更してください。

    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <script type="text/javascript">google.load("jquery", "1.2");</script>
    <script type="text/javascript" src="http://www.tinybeans.net/blog/js/newmark_jquery.js" charset="UTF-8"></script>

後は、New マークを表示させたいリンクに class="newmarkList" を設定すればOKです。経過時間や New マークの設定も忘れずに。

Movable Type で使う場合

Movable Type で使う場合は、MT タグを使えばさらに自動化できます。例えば、以下のようになります。

【 newmark クラスの要素に追加する title 属性】

title="<$mt:EntryDate format="%Y年%m月%d日 %H時%M分%S秒"$> に作成 (<$mt:EntryCategory$>)"
title="<$mt:EntryDate format="%Y年%m月%d日 %H時%M分%S秒"$> に作成されたブログ記事 (<$mt:EntryTitle$>)"

【 経過時間と New マーク画像の設定】

        var pass       // passage time<mt:SetVar name="pass" value="72">
             = <$mt:GetVar name="pass"$>;
        var content    // display content<mt:SetVar name="pass" op="/" value="24">
             = '<img class="newmark" src="<$mt:BlogURL$>img/icon/newmark.gif" alt="<$mt:GetVar name="pass"$>日以内の新着ブログ記事" width="15" height="15" title="<$mt:GetVar name="pass"$>日以内の新着ブログ記事"/>';

ちなみに、これを再構築すると次のようになります。「日」単位でやるときに便利です。

        var pass       // passage time
             = 72;
        var content    // display content
             = '<img class="newmark" src="http://www.tinybeans.net/blog/img/icon/newmark.gif" alt="3日以内の新着ブログ記事" width="15" height="15" title="3日以内の新着ブログ記事"/>';

Movable Type 用のテンプレートファイルを以下においておきます。このファイルを解凍して、新たにインデックステンプレートを作成し、出力ファイル名を「 newmark_jquery.js 」などにすればOKです。

WordPress で使う場合

WordPress でも同様にテンプレートタグを使えば自動化できます。

【 newmark クラスの要素に追加する title 属性】

title="<?php the_modified_time('Y年m月d日 H時i分s秒 に更新'); ?>"
【2008-09-25 追記】

正規表現で置換する部分が間違っていたので訂正しました。MT 用のテンプレートファイルも訂正しました。

以上です。

  • このエントリーをはてなブックマークに追加
Just a second...