日々のコンピュータ情報の集積と整理

Dr.ウーパのコンピュータ備忘録

2014年12月11日木曜日

遅延読み込み機能追加-Feedから情報取得-Blogger:「次の投稿・前の投稿」にページタイトルを付与する

イントロダクション

Google のブログサービス「Blogger」では、現在表示している投稿の「次の投稿」「前の投稿」ナビゲータにはタイトルが付与されません。

そこで、以前の投稿では「次の投稿」「前の投稿」のリンクの URL を用いて、それらのページのフィードからページタイトルを取得し、「次の投稿」「前の投稿」へページタイトルを付与する JavaScript を作成しました。



Blogger:「次の投稿・前の投稿」にページタイトルを付与する-Feedから情報取得 - Dr.ウーパのコンピュータ備忘録
http://upa-pc.blogspot.jp/2014/12/blogger-prev-next-page-title-script.html

Blogger の「前の投稿」「次の投稿」ナビゲータ
JavaScript によってページタイトルを表示できるようになった


Feed の読み込みに伴う、読み込み時の負荷対策

以前作成した JavaScript コードでは、ページの読み込み時に「次の投稿」「前の投稿」のFeed を取得し、ページタイトルを取得していました。

そのため、「次の投稿」「前の投稿」のフィードを取得するコストと、それらを解析して表示するコストが、ページの読み込み時に発生してしまい、ページの表示を遅くする一因になってしまいます。

ページを表示する流れ(以前の JavaScript コードの場合)
ブログページの HTML 取得
 ↓
ブログページの HTML 解析・各種参照リソース取得(「次の投稿」「前の投稿」のフィード取得含む)
 ↓
ブログページ表示完了


「次の投稿」「前の投稿」ナビゲータは、ページの下部にあるため、ページが表示された初期の段階からタイトルが付与されている必要は無いはずです。

そのため、「次の投稿」「前の投稿」ナビゲータのタイトルを取得する処理を後回しにして、その代わりに他のページ要素を表示する処理を優先した方が、ユーザの利便性が向上するはずです。


そこで、今回は「次の投稿」「前の投稿」のフィード取得から、それらを解析して表示するまでの処理を遅延して実行できるようにコードを修正しました。

ページを表示する流れ(今回作成する JavaScript コードの場合)
ブログページの HTML 取得
 ↓
ブログページの HTML 解析・各種参照リソース取得
 ↓
ブログページ表示完了(第1段階)
 ↓
「次の投稿」「前の投稿」のフィード取得/解析/表示
 ↓
ブログページ表示完了(最終段階)


コード

<!-- set next prev page title start -->
<script type='text/javascript'>
//<![CDATA[
<!--
(function () {

    // --- Util ---

    // JavaScript動的挿入
    function addScript(src) {

        var script = document.createElement('script');
        script.setAttribute("type", "text/javascript");
        script.setAttribute("src", src);

        header_setChild(script);
    }

    // <head>取得
    function getHeader() {
        return document.getElementsByTagName("head")[0];
    }

    // <head>に子要素を追加
    function header_setChild(child) {
        var head = getHeader();
        head.appendChild(child);
    }


    // --- Main ---

    // 各種パラメータ
    var feed_load_delay = 5000;             // 前の投稿・次の投稿のフィードを読み込むまでの遅延時間(単位:ミリ秒)


    // 前の投稿の要素が存在したら、タイトル設定
    var prev_page_link_obj = document.getElementById("Blog1_blog-pager-older-link");
    if (prev_page_link_obj) {
        var prev_page_link_url = prev_page_link_obj.getAttribute("href");
        addPageTitleFromFeed("blog-pager-older-link", prev_page_link_url, "addPrevPageTitle");
    }

    // 次の投稿の要素が存在したら、タイトル設定
    var next_page_link_obj = document.getElementById("Blog1_blog-pager-newer-link");
    if (next_page_link_obj) {
        var next_page_link_url = next_page_link_obj.getAttribute("href");
        addPageTitleFromFeed("blog-pager-newer-link", next_page_link_url, "addNextPageTitle");
    }


    /*
       ページのタイトルをフィードから取得し、対象のオブジェクトへ追加する

       ins_obj_id : 対象のオブジェクトの id
       page_url : タイトルをフィードから取得するページの URL
    callback : フィードのデータを取得するためのコールバック
    */
    function addPageTitleFromFeed(ins_obj_id, page_url, callback) {

        if (!ins_obj_id) return;
        if (!page_url) return;
        if (page_url.indexOf("?") != -1) return;        // クエリ文字列が含まれているURLは対象外


        // Feed の path に指定する URL を作成
        var home_url = location.protocol + "//" + location.hostname + "/";      // ブログのホームの URL
        var page_url_remove_home = page_url.replace(home_url, "");              // ブログのホームの URLを除いた、タイトルをフィードから取得するページの URL
        if (!page_url_remove_home) return;              // 対象とするページのURLが無い場合は対象外
        page_url_remove_home = "/" + page_url_remove_home;


        // ページタイトルの挿入先を事前に生成
        var div = document.createElement("div");
        var title_obj_id = ins_obj_id + "-title";
        div.innerHTML = "<a href=\"" + page_url + "\" id=\"" + title_obj_id + "\">" + "now loading..." + "</a>";


        var obj = document.getElementById(ins_obj_id);
        if (!obj) return;
        obj.appendChild(div);


        setTimeout(function () {
            // フィードを取得し、コールバック
            addScript(home_url + "feeds/posts/summary?alt=json-in-script&callback=" + callback + "&max-results=1&path=" + page_url_remove_home + "&redirect=false");
        }, feed_load_delay);
    }

})();

/*
 前の投稿のページタイトルを設定する
 data : コールバックで渡される Feed のデータ
*/
function addPrevPageTitle(data) {
    addPageTitle(data, "blog-pager-older-link-title");
}

/*
 次の投稿のページタイトルを設定する
 data : コールバックで渡される Feed のデータ
*/
function addNextPageTitle(data) {
    addPageTitle(data, "blog-pager-newer-link-title");
}

/*
 ページのタイトルを設定する
 data : コールバックで渡される Feed のデータ
 id : タイトルの設定先
*/
function addPageTitle(data, id) {

    // ページのタイトルを取得
    var title = "";
    if (data.feed.entry) {
        if (data.feed.entry.length > 0) {
            title = escapeHTML(data.feed.entry[0].title.$t);
        }
    }

    // ページのタイトルを設定
    var obj = document.getElementById(id);
    if (!obj) return;
    obj.innerHTML = title;


    // テキストをエスケープ処理する
    function escapeHTML(html) {

        var div = document.createElement("div");
        if (div.innerText !== void 0) div.innerText = html;          // innerText が定義されていれば innerText へ設定
        else div.textContent = html;                                 // Firefox のように innerText がないブラウザ向け

        return div.innerHTML;
    }
}
//-->
//]]>
</script>
<!-- set next prev page title end -->


※なお、ブログの構造によっては、一部要素の id が異なる可能性があります。その場合には、各自のブログの構造に合わせて id を書き換えてください。


「次の投稿」「前の投稿」のフィード取得を遅延させる時間を変数 feed_load_delay に設定します。
ここでは、5000 (ミリ秒) を設定しています。

    // 各種パラメータ
    var feed_load_delay = 5000;             // 前の投稿・次の投稿のフィードを読み込むまでの遅延時間(単位:ミリ秒)


実際に、読み込みの遅延の処理を実施している部分は、以下の箇所です。

        setTimeout(function () {
            // フィードを取得し、コールバック
            addScript(home_url + "feeds/posts/summary?alt=json-in-script&callback=" + callback + "&max-results=1&path=" + page_url_remove_home + "&redirect=false");
        }, feed_load_delay);

setTimeout に、フィードを取得する処理を指定することで、その部分の処理を遅延させています。

設置方法

Blogger の設定のテンプレート→HTMLの編集にて、上記のコードを</body>の手前に設置します。

Blogger の設定のテンプレート→HTMLの編集にて、 コードを</body>の手前に張り付けた状態
Blogger の設定のテンプレート→HTMLの編集にて、
コードを</body>の手前に張り付けた状態


設置が完了したら、テンプレートをプレビューにて、ブログが正常に表示されることを確認したのち、テンプレートの保存を行います。


結果

以下のように、ページ読み込み時は "now loading..." が表示された後、指定時間後(ブラウザの処理が追いついていない場合には、それ以上)に、ページタイトルが表示されます。

Blogger の「前の投稿」「次の投稿」ナビゲータ ページタイトル取得待ち状態
Blogger の「前の投稿」「次の投稿」ナビゲータ
ページタイトル取得待ち状態
 ↓(指定時間経過後)

Blogger の「前の投稿」「次の投稿」ナビゲータ ページタイトル取得完了状態
Blogger の「前の投稿」「次の投稿」ナビゲータ
ページタイトル取得完了状態


動作確認環境

このプログラムが動作することを以下の環境で確認しました。
  • Chrome バージョン 39.0.2171.71 m
  • Firefox バージョン 34.0
  • Internet Explorer バージョン 9.0.8112.16421


まとめ

ブログ記事を投稿順に追っていく場合には、「前の投稿」「次の投稿」ナビゲータに、そのページのタイトルが表示されていると、次にどんなページが来るのかイメージしやすく、次のページへ移動する動機づけになると思います。

そして、ブログのページの表示が軽快というのも、ブログ内のページを移動するうえでは重要な要素です。


使いやすい・見やすい・快適なブログのために、是非このコードを使ってみてください。







関連記事

関連記事を読み込み中...

同じラベルの記事を読み込み中...