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

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

2014年6月4日水曜日

Blogger:投稿に付与されているラベル名をラベルウィジットの中からハイライト

イントロダクション

いろいろなラベルを記事に付与していると、ラベルウィジットに大量のラベルが表示されるようになります。
そうなると、今表示している投稿のラベルがどこにあるのかすらわからなくなります。

そこで、現在表示している投稿に付与されているラベルについて、ラベルウィジット中のラベルをハイライトするようにしました。


なお、本コードはクラウド形式でラベルを表示している Blogger のブログに対して有効です。リスト形式でラベルを表示しているものに対しては使えません。

Blogger側の準備

記事の下部のラベルを参照できるように、Blogger のテンプレートの HTML の編集にて、<span class='post-labels'>へ、 id='post-label-bottom'を付与しました。

<div class='post-footer-line post-footer-line-2'>
    <span class='post-labels' id='post-label-bottom'>   <!-- ラベルを参照するために id を追加 -->
    <b:if cond='data:post.labels'>
        <data:postLabelsLabel/>
        <b:loop values='data:post.labels' var='label'>
        <a expr:href='data:label.url' rel='tag'>
            <data:label.name/>
        </a>
        <b:if cond='data:label.isLast != &quot;true&quot;'>
            ,
        </b:if>
        </b:loop>
    </b:if>
    </span>
</div>


スタイルシート

ラベルのハイライト用に以下のスタイルシートを、Bloggerのテンプレートのカスタマイズ→上級者向け→CSSを追加 にて、追加します。

/* 投稿に含まれるラベルのハイライト */
.label-hilight {
background-color: #ffffee;
border-color: #ccccbb;
border-style: solid;
border-width: 1px;
font-weight: bold;
}


JavaScriptコード

以下の JavaScript コードにより、ラベルウィジット中のラベルのハイライトを実現します。

動きとしては次のようになっています。

(1) 投稿の下部のラベル一覧より、ラベル名の一覧を取得する
(2) ラベルウィジット中のハイライト対象のラベルにクラス名(label-hilight)を付与

<script type='text/javascript'>
<!--
    (function () {

        // --- Util ---

        /*
        タグ名から子要素のみを選択して取得する
        */
        function getChildElementsByTagName(obj, tagName) {
            var items = new Array();

            for (var i = 0; i < obj.childNodes.length; i++) {
                if (obj.childNodes[i].tagName !== void 0)          // undefined でなければ処理
                {
                    if (obj.childNodes[i].tagName.toLowerCase() == tagName.toLowerCase()) {
                        items.push(obj.childNodes[i]);
                    }
                }
            }

            return items;
        }


        // --- Main ---

        /*
        ラベルウィジェットの指定したラベル名をハイライトする

        id_label_widget : ラベルウィジェットの id
        labels : ハイライトするラベル一覧
        */
        function hilightLabelsFromLabelNames(id_label_widget, labels) {

            var obj_label_widget = document.getElementById(id_label_widget);

            // label ウィジェット内の、ラベル名と投稿数のペアーが収められている<span>要素の上位要素を取得
            var obj_label_widget_labels_tops = getChildElementsByTagName(obj_label_widget, "div");
            if (obj_label_widget_labels_tops.length == 1) {

                // ラベル名と投稿数のペアーが収められている<span>要素取得
                var obj_label_widget_labels_spans = getChildElementsByTagName(obj_label_widget_labels_tops[0], "span");

                for (var i = 0; i < obj_label_widget_labels_spans.length; i++) {
                    if (obj_label_widget_labels_spans[i].className.match(/^label-size label-size/)) {

                        // ラベル名を取得
                        var obj_a_Tags = getChildElementsByTagName(obj_label_widget_labels_spans[i], "a");
                        if (obj_a_Tags.length != 1) {
                            continue;
                        }

                        // ラベル名がハイライト対象かどうかをチェック
                        for (var j = 0; j < labels.length; j++) {
                            if (obj_a_Tags[0].innerHTML == labels[j]) {

                                // ハイライト用のクラスを追加
                                obj_label_widget_labels_spans[i].className += " label-hilight";
                            }
                        }
                    }
                }
            }
        }

        /*
        投稿に付与されているラベル名の一覧を取得する

        id_post_label : 投稿のラベルの id
        */
        function getLabels(id_post_label) {
            var labels = [];
            var obj_post_label = document.getElementById(id_post_label);

            // 投稿のラベルの一覧を取得し、ラベル名のみ取得
            var obj_post_label_items = getChildElementsByTagName(obj_post_label, "a");
            for (var i = 0; i < obj_post_label_items.length; i++) {

                // ラベル名取得
                var labelName = obj_post_label_items[i].innerHTML;
                labels.push(labelName);
            }

            return labels;
        }


        // ラベルをハイライトする
        function hilightLabel(id_post_label, id_label_widget) {

            var labels = getLabels(id_post_label);          // 投稿のラベル名一覧を取得

            // ラベルのハイライトを実行する
            hilightLabelsFromLabelNames(id_label_widget, labels);

        }

        hilightLabel("post-label-bottom", "Label1");

    })();
//-->
</script>


なお、ラベルウィジットの id "Label1" は環境によって異なる可能性があるので、ラベルウィジットの id を調べてその id を hilightLabel の第2引数に指定します。


最適化した JavaScript コードのBloggerへの貼り付け

上記のコードを、Closure Compiler(Googleが提供しているコード圧縮・最適化ツール)にて最適化しました。
Blogger への設置のため、<b:if></b:if>の追加と、<script type="text/javascript"></script>のすぐ内側に//<![CDATA[ と //]]> を追加しています

<b:if cond='data:blog.pageType == &quot;item&quot;'>
      <!-- 投稿ページにのみ ラベルのハイライト を適用する -->
      <!-- ラベルのハイライト START -->
    <script type='text/javascript'>
    //<![CDATA[
    <!--
(function(){function c(d,c){for(var e=[],a=0;a<d.childNodes.length;a++)void 0!==d.childNodes[a].tagName&&d.childNodes[a].tagName.toLowerCase()==c.toLowerCase()&&e.push(d.childNodes[a]);return e}(function(d,h){for(var e=[],a=document.getElementById(d),a=c(a,"a"),b=0;b<a.length;b++)e.push(a[b].innerHTML);a=document.getElementById(h);a=c(a,"div");if(1==a.length)for(a=c(a[0],"span"),b=0;b<a.length;b++)if(a[b].className.match(/^label-size label-size/)){var g=c(a[b],"a");if(1==g.length)for(var f=0;f<e.length;f++)g[0].innerHTML==
e[f]&&(a[b].className+=" label-hilight")}})("post-label-bottom","Label1")})();

    //-->
    //]]>
    </script>
      <!-- ラベルのハイライト END -->
</b:if>


このコードを Blogger のテンプレートの HTML の編集にて、</body>直前に設置しました。
(このコードが正しく動作するには、このコードの設置位置は少なくとも記事のラベルやラベルウェジェットよりも後に設置する必要があります。)

また、以前「Blogger:記事の下部のラベルへ件数を付与するようにした(JavaScript編)」にて、記事の下部のラベルへ件数を追加するコードを紹介しましたが、そのコードを使用している場合、そのコードよりも早く実行されるよう、そのコードよりも上にコードを張り付けてください。


結果

以下のように、現在表示している投稿のラベルを、ラベルウィジット中でハイライト出来ました。

現在表示ている投稿のラベルをハイライト


これで、閲覧者は大量のラベルの中から、どこに現在表示している投稿のラベルがあるのか悩まなくて済みます。


なお、このコードは投稿ページでのみ動作します。
Blogger のトップページや、記事の検索、過去の記事一覧などでは動作しません。





関連記事

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

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