イントロダクション
記事「Blogger:記事の下部のラベルへラベルの件数を付与するようにしたかったが失敗した(テンプレートのHTML編集編)」では、記事の下部のラベルへ件数を付与するようにしようとしたのですが、失敗しました。今度は JavaScript で 記事の下部のラベルへ件数を付与するようにしました。
なお、本コードはクラウド形式でラベルを表示している 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 != "true"'> , </b:if> </b:loop> </b:if> </span> </div>
JavaScriptコード
記事の下部のラベルへ件数を付与する JavaScript を作成しました。このコードの主な動きは次のとおりです。
(1) ラベルウィジェット内のラベル名と件数を配列に記憶させる
(2) 記事の下部のラベルを解析し、(1)で記憶したデータの中からラベル名に対応する件数を取得し、記事の下部のラベルへ件数を追加
(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 --- // ラベルのラベル名とカウントのペアー function CLabelItem(name, count) { this.name = name; this.count = count; } // ラベル名とカウント数のペアの配列データ var labelItems = getLabelItems("Label1"); /* ラベルウィジェットから、ラベル名とカウントのペアーを取得する id_label_widget : ラベルウィジェットの id */ function getLabelItems(id_label_widget) { var items = new Array(); 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/)) { // ラベル名の a タグと、カウント数の span タグが入っていることを確認 var obj_a_Tags = getChildElementsByTagName(obj_label_widget_labels_spans[i], "a"); if (obj_a_Tags.length != 1) { continue; } var obj_span_Tags = getChildElementsByTagName(obj_label_widget_labels_spans[i], "span"); if (obj_span_Tags.length != 1) { continue; } items.push(new CLabelItem(obj_a_Tags[0].innerHTML, obj_span_Tags[0].innerHTML)); } } } // ラベル名からカウント数を取得するメソッドを追加 items.getCount = function (name) { for (var i = 0; i < items.length; i++) { if (items[i].name == name) { return items[i].count; } } return ""; }; return items; } // --- ここにラベル名に、同様のラベルが付与されている投稿の件数を追加する対象分だけメソッド呼び出しを記載 label_addPostCount("post-label-bottom"); /* 投稿のラベルに、同様のラベルが付与されている投稿の件数を追加する id_post_label : 投稿のラベルの id */ function label_addPostCount(id_post_label) { 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; // カウント数取得 var count = labelItems.getCount(labelName); // カウント数をラベルに付与 obj_post_label_items[i].innerHTML += count; } } })();
最適化した JavaScript コードのBloggerへの貼り付け
上記のコードを、Closure Compiler(Googleが提供しているコード圧縮・最適化ツール)にて最適化しました。Blogger への設置のため、<b:if></b:if>の追加と、<script type="text/javascript"></script>のすぐ内側に//<![CDATA[ と //]]> を追加しています
<b:if cond='data:blog.pageType == "item"'> <!-- 投稿ページにのみ 投稿のラベルへの件数の追加 を適用する --> <!-- 投稿のラベルへの件数の追加 START --> <script type='text/javascript'> //<![CDATA[ <!-- (function(){function e(a,b){for(var c=[],d=0;d<a.childNodes.length;d++)void 0!==a.childNodes[d].tagName&&a.childNodes[d].tagName.toLowerCase()==b.toLowerCase()&&c.push(a.childNodes[d]);return c}function g(a,b){this.name=a;this.count=b}var h=function(a){var b=[];a=document.getElementById(a);a=e(a,"div");if(1==a.length){a=e(a[0],"span");for(var c=0;c<a.length;c++)if(a[c].className.match(/^label-size label-size/)){var d=e(a[c],"a");if(1==d.length){var f=e(a[c],"span");1==f.length&&b.push(new g(d[0].innerHTML, f[0].innerHTML))}}}b.getCount=function(a){for(var c=0;c<b.length;c++)if(b[c].name==a)return b[c].count;return""};return b}("Label1");(function(a){a=document.getElementById(a);a=e(a,"a");for(var b=0;b<a.length;b++){var c=h.getCount(a[b].innerHTML);a[b].innerHTML+=c}})("post-label-bottom")})(); //--> //]]> </script> <!-- 投稿のラベルへの件数の追加 END --> </b:if>
このコードを Blogger のテンプレートの HTML の編集にて、</body>直前に設置しました。
(このコードが正しく動作するには、このコードの設置位置は少なくとも記事のラベルやラベルウェジェットよりも後に設置する必要があります。)
結果
以下のように、見事ラベルの投稿件数を記事の下部のラベルへ追加することが出来ました。
Blogger : 記事の投稿件数を、記事の下部のラベル表示部へ追加
これで、ラベルウィジェットを参照しなくても、同じラベルを付与した記事が何件あるのか、読者がすぐにわかるようになりました!
なお、このコードは投稿ページでのみ動作します。
Blogger のトップページや、記事の検索、過去の記事一覧などでは動作しません。
コメントを投稿
コメント投稿機能について