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

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

2015年3月28日土曜日

Blogger:人気の投稿の表示期間をクリックで切り替え(改良版,画像の遅延読み込み)

イントロダクション

以前、Google のブログサービス「Blogger」にて、人気の投稿の表示期間(全期間, 過去 30 日間, 過去 7 日間)を切り替えられる仕組みを作ってみました。


Blogger:人気の投稿の表示期間をクリックで切り替え(改良版)
http://upa-pc.blogspot.com/2015/02/blogger-popular-post-change-advance.html
Dr.ウーパのコンピュータ備忘録



それを実際に、このブログの人気の投稿として運用しているのですが、少し気になっている部分がありました。

それは、”見えていない”人気の投稿の期間の分まで、ページの読み込み時に投稿のサムネイル画像が読み込まれるという点です。


読み込み時の負荷を減らしたいという点では、”見えていない”人気の投稿の期間の投稿のサムネイル画像は、実際に見えるようになるときに読み込みたいものです。


そこで、今回は、前回作成した JavaScript コードと、Blogger のテンプレートの HTML に手を加えることで、”見えていない”人気の投稿の期間の投稿のサムネイル画像を、実際に見えるようになるときに読み込むように改良します。

Blogger:人気の投稿の表示期間をクリックで切り替え(改良版,画像の遅延読み込み)

前提条件

前回の「Blogger:人気の投稿の表示期間をクリックで切り替え(改良版)」で作成した環境を前提とします。

そのため、今回の記事では説明していない事柄があります。
必ず、前回の記事を参照してください。


JavaScript コード

このソースコードを、</body> の手前に設置します。

<!-- 人気の投稿-期間変更 START -->
<script type='text/javascript'>
    //<![CDATA[
    <!--
    (function () {
     
        /*
        Blogger ブログの状況に応じた設定
        必要に応じて、この部分を自身の Blogger の設定に書き換える必要があります
        */
        var popular_post_all = {id:"PopularPosts1", name:"全期間"};
        var popular_post_30days = {id:"PopularPosts3", name:"過去 30 日間"};
        var popular_post_7days = {id:"PopularPosts2", name:"過去 7 日間"};

        var top_popular_post_id = popular_post_all.id;                  // 人気の投稿ガジェット群の先頭の要素の id
        var default_popular_post_id = popular_post_7days.id;            // 最初に表示する人気の投稿の id
        /* Blogger ブログの状況に応じた設定 ここまで */

        /*
        その他リソース
        */
        var chage_popular_post_navi_id = "change-popular-post-navi";    // 人気の投稿の期間変更用ナビゲーションの id
        var display_popular_post_id = default_popular_post_id;          // 現在表示されている人気の投稿の id


        // 人気の投稿の切り替え
        function changePopularPost(id) {
         
            if ( display_popular_post_id != id ) {

                var obj_old = document.getElementById(display_popular_post_id);
                var obj_new = document.getElementById(id);

                obj_old.style.display = "none";
                obj_new.style.display = "block"

                // ナビゲーション更新
                var obj_navi = document.getElementById(chage_popular_post_navi_id);
                obj_navi.innerHTML = "";
                obj_navi.appendChild(getPopularPostNavigationObject(id));

                display_popular_post_id = id;


                // 画像がまだ読み込まれていなかったらロードする
                var obj_imgs = obj_new.getElementsByTagName("img");
                if ( obj_imgs ) {
                    for ( var i = 0; i < obj_imgs.length; i++ ) {
                        
                        // src にはデフォルトの画像の URL が記載されているので、
                        // data-src が空になっていないことで、データがあることを確認する
                        var data_src = obj_imgs[i].getAttribute("data-src");
                        if ( data_src ) {

                            obj_imgs[i].setAttribute("src", data_src);
                            obj_imgs[i].setAttribute("data-src", "");
                        }
                    }
                }
            }
        }

        // 人気の投稿の切り替えナビゲーションを取得
        function getPopularPostNavigationObject(id) {
      
            // ナビゲーションの要素を作成
            function createNaviItem(id, select, title) {
                var obj_item = document.createElement("a");
                obj_item.setAttribute("href", "javascript:void(0);");
                obj_item.innerHTML = title;
                if ( select ) {
                    obj_item.setAttribute("style", "background-color:#ffffcc;");
                }

                obj_item.onclick = function() {
                    changePopularPost(id);
                };

                return obj_item;
            }

            // ナビゲーションの要素を要素へ追加
            function appendNaviItem(obj, id_select, id_this, title) {
                obj.appendChild(createNaviItem(id_this, id_select == id_this, title));
            }

            var obj_navi = document.createElement("span");
            appendNaviItem(obj_navi, id, popular_post_all.id, popular_post_all.name);
            obj_navi.appendChild(document.createTextNode(" | "));
            appendNaviItem(obj_navi, id, popular_post_30days.id, popular_post_30days.name);
            obj_navi.appendChild(document.createTextNode(" | "));
            appendNaviItem(obj_navi, id, popular_post_7days.id, popular_post_7days.name);

            return obj_navi;
        }

        // 切り替え可能な人気の投稿の準備
        function initChangePopularPost() {
         
            // 先頭の人気の投稿を取得し、上部にナビゲーションを設定
            var obj_popular_post_top = document.getElementById(top_popular_post_id);
         
            var obj_navi = document.createElement("div");
            obj_navi.setAttribute("id", chage_popular_post_navi_id);
            obj_navi.appendChild(getPopularPostNavigationObject(default_popular_post_id));
            obj_popular_post_top.parentNode.insertBefore(obj_navi, obj_popular_post_top);
        }

        // 遅延して実行
        setTimeout(initChangePopularPost, 0);
    })();

    //-->
    //]]>
</script>
<!-- 人気の投稿-期間変更 END -->


CSS 

CSS は、前回と同様のまま変更なしです。


Blogger のテンプレートの HTML へ埋め込み

ページ読み込み時に非表示とする Blogger の人気の投稿ガジェットの HTML を編集します。


私の場合には、ページ読み込み時に非表示とする Blogger の人気の投稿ガジェットの id 属性の値は、PopularPosts1, PopularPosts3 なので、それらの両方に適用しました。


また、私の場合、人気の投稿ガジェットの設定は、サムネイルとタイトルのみのため、「<!-- (3) Show only thumbnails -->」の部分を修正します。
要約付きなどの設定にしている場合には、別の場所を修正する必要があります。


なお、Blogger のテンプレートの HTML の編集には危険を伴います。
次のページの注意事項をお読みください。

Blogger:BloggerのテンプレートのHTMLを編集するときに気を付けること
http://upa-pc.blogspot.com/2015/03/blogger-template-edit-attention.html
Dr.ウーパのコンピュータ備忘録


変更前

            <!-- (3) Show only thumbnails -->
            <div class='item-thumbnail-only'>
              <b:if cond='data:post.thumbnail'>
                <div class='item-thumbnail'>
                  <a expr:href='data:post.href' target='_blank'>
                   <img alt='' border='0' expr:src='data:post.thumbnail' height='100px' width='100px'/>
                  </a>
                </div>
              <b:else/>
                <div class='item-thumbnail'>
                  <a expr:href='data:post.href' target='_blank'>
<img alt='' border='0' src='http://2.bp.blogspot.com/-I6V67vNeOds/VEsE4kMX4eI/AAAAAAAACsk/3OBiRLi9AMQ/s72-c/post_image.png' height='100px' width='100px'/>                  </a>
                </div>
              </b:if>
              <div class='item-title'><a expr:href='data:post.href'><data:post.title/></a></div>
            </div>
            <div style='clear: both;'/>


変更後

            <!-- (3) Show only thumbnails -->
            <div class='item-thumbnail-only'>
              <b:if cond='data:post.thumbnail'>
                <div class='item-thumbnail'>
                  <a expr:href='data:post.href' target='_blank'>
                    <img alt='' border='0' expr:data-src='data:post.thumbnail' height='100px' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAAEElEQVR42mL4//8/A0CAAQAI/AL+26JNFgAAAABJRU5ErkJggg==' width='100px'/>
                  </a>
                </div>
              <b:else/>
                <div class='item-thumbnail'>
                  <a expr:href='data:post.href' target='_blank'>
                    <img alt='' border='0' data-src='http://2.bp.blogspot.com/-I6V67vNeOds/VEsE4kMX4eI/AAAAAAAACsk/3OBiRLi9AMQ/s72-c/post_image.png' height='100px' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAAEElEQVR42mL4//8/A0CAAQAI/AL+26JNFgAAAABJRU5ErkJggg==' width='100px'/>
                  </a>
                </div>
              </b:if>
              <div class='item-title'><a expr:href='data:post.href'><data:post.title/></a></div>
            </div>
            <div style='clear: both;'/>


変更前から、変更後の赤字・太字の部分のように、修正します。
なお、下記に記載する理由により、標準の人気の投稿ガジェットでは、赤字・太字に橙色の背景色を適用した部分は無いはずです。

私の場合、次の二つの修正を人気の投稿ガジェットへ適用しているため、標準の人気の投稿ガジェットの HTML とは異なっています。


Blogger:人気の投稿ガジェットで画像のサムネイルが無い場合には指定した画像を表示する
http://upa-pc.blogspot.com/2014/10/blogger-popular-post-thumbnail.html
Dr.ウーパのコンピュータ備忘録
Blogger:人気の投稿ガジェットのサムネイル画像を大きくする
http://upa-pc.blogspot.com/2014/10/blogger-popular-post-thumbnail-zoom.html
Dr.ウーパのコンピュータ備忘録


解説

基本的な考え方としては、”見えていない”人気の投稿の期間の投稿のサムネイル画像を、見えるようになった時に動的に読み込むために、次の JavaScript コードを追加しています。

                // 画像がまだ読み込まれていなかったらロードする
                var obj_imgs = obj_new.getElementsByTagName("img");
                if ( obj_imgs ) {
                    for ( var i = 0; i < obj_imgs.length; i++ ) {
                     
                        // src にはデフォルトの画像の URL が記載されているので、
                        // data-src が空になっていないことで、データがあることを確認する
                        var data_src = obj_imgs[i].getAttribute("data-src");
                        if ( data_src ) {

                            obj_imgs[i].setAttribute("src", data_src);
                            obj_imgs[i].setAttribute("data-src", "");
                        }
                    }
                }


このコードでは、img タグの 独自に定義した属性である data-src の値に画像ファイルへの URL が入っていれば、その URL を img タグの src 属性の値として設定することで、画像を動的に読み込んでいます。

そのために、Blogger のテンプレートの HTML を編集して、

                    <img alt='' border='0' expr:data-src='data:post.thumbnail' height='100px' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAAEElEQVR42mL4//8/A0CAAQAI/AL+26JNFgAAAABJRU5ErkJggg==' width='100px'/>


という形にしています。
元々 src 属性の値として使用されていた値は、data-src 属性の値として使用し、新たにデフォルトの画像を src として追加しています。

src には、横1ピクセル×縦1ピクセルの透明の png 画像を埋め込んでいます。
なぜ、src に横1ピクセル×縦1ピクセルの透明の png 画像を埋め込んでいるのかというと、img タグの src 属性の値は指定しなければならないという決まりだからです。

src
画像の URL です。この属性は、<img> 要素に必須です。

より引用


まとめ

以上のように設定することで、Bloggerの人気の投稿の表示期間をクリックで切り替えられるようにしたものに対して、”見えていない”人気の投稿の期間の投稿のサムネイル画像を、実際に見えるようになるときに読み込むようにすることが出来ました。






関連記事

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

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