http://www.masaemon.jp/
上記ブログ(PC版)右サイドバー下段にカテゴリ一覧を表示しているのですが、カテゴリの量が多く縦長すぎるのが悩みです。そこで以下のようにできるか教えてください。
ーーーーーーーーーー
【現在】
【東京】上野・浅草・日暮里 (34)
【東京】両国・錦糸町・小岩 (2)
【東京】中野~西荻窪 (7)
…続く
【希望】
▶東京
おでん
…続く
↓右三角をクリックすると↓
▼東京
【東京】上野・浅草・日暮里 (34)
【東京】両国・錦糸町・小岩 (2)
【東京】中野~西荻窪 (7)
…続く
ーーーーーーーーーー
【補足説明】
・月別アーカイブのように右三角(▶)をクリックするとサブカテゴリを表示します。
・今後カテゴリが増えるにあたって、いちいち編集とかせず自動でサブカテゴリが反映できたりすると尚最高です。
・カテゴリ一覧をコンパクトに使い勝手のいいものにできればその方法を回答いただいてもOKです。
・回答には、実装結果を確認できるはてなブログURLが必須です。
以下のコードを、「デザイン」の「ヘッダ」の「タイトル下」のところにペタッと。
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script> (function($) { $(function() { var re = /【(.*)】.*\((.*)\)/; var forEach = Array.prototype.forEach; var cat_name_map = {}; forEach.call(document.querySelectorAll("div.hatena-module-category ul.hatena-urllist li a"), function(a) { var match = re.exec(a.textContent); if (match) { var cat = match[1]; var ar = cat_name_map[cat]; if (! ar) { ar = [0, 0]; } ar[0] += 1; ar[1] += parseInt(match[2]); cat_name_map[cat] = ar; } }); var cat_node_map = {}; forEach.call(document.querySelectorAll("div.hatena-module-category ul.hatena-urllist li a"), function(a) { var match = re.exec(a.textContent); if (match) { var cat = match[1]; if (cat_name_map[cat][0] > 1) { var original_item = a.parentNode; var new_item = document.createElement("LI"); new_item.innerHTML = original_item.innerHTML; new_item.style.paddingLeft = "2em"; var sub_category_list = cat_node_map[ cat ]; if (! sub_category_list) { /* LI : original_item | V LI : sub_category_parent SPAN : arrow SPAN : label UL : sub_category_list LI : new_item */ var sub_category_parent = document.createElement("LI"); original_item.parentNode.insertBefore(sub_category_parent, original_item); var arrow = document.createElement("SPAN"); arrow.innerHTML = "▶"; arrow.style.cursor = "pointer"; arrow.onclick = function() { var sub_category_list = this.nextSibling.nextSibling; if (sub_category_list.style.display == "none") { this.innerHTML = "▼"; sub_category_list.style.display = ""; } else { this.innerHTML = "▶"; sub_category_list.style.display = "none"; } }; sub_category_parent.appendChild(arrow); var label = document.createElement("SPAN"); label.innerHTML = cat + " (" + cat_name_map[cat][1] + ")"; sub_category_parent.appendChild(label); sub_category_list = document.createElement("UL"); sub_category_list.style.display = "none"; sub_category_parent.appendChild(sub_category_list); cat_node_map[ cat ] = sub_category_list; } sub_category_list.appendChild(new_item); original_item.parentNode.removeChild(original_item); } } }); }); })(jQuery); </script>
サブカテゴリは、【】でくくられたものを拾ってます。
サブカテゴリのカテゴリ数がひとつだけの場合には、折りたたむ意味がないので、そのまま表示するようにしました。
クリックできるのは、ちょっと狭いかなという気もしますが、三角のところだけにしてます。
・回答には、実装結果を確認できるはてなブログURLが必須です。
カテゴリのデータを作るのが大変面なので、id:thyself2005 さんのはてなブログで、Bookmarklet として動作確認しました。
こういう感じになります。
1.今後【】でくくる複数のカテゴリを追加する場合、特に追加作業等発生せずそれらもサブカテゴリ化できるということでしょうか?
【】でくくられた文字を親カテゴリだと判断するようにしてますので、カテゴリが追加された場合には それに追従します。
2.カテゴリのクリックできる範囲と見た目を月別アーカイブの体裁に揃えることはできますか?
※例えば「? 東京 (XXX)」だと東京 (XXX)も青緑色の下線リンクとなっており、▶ と東京の間の間隔が半角スペース1個分くらい空いている感じです。
月別アーカイブの見た目に寄せることはできますが、月別アーカイブの場合には「年」をクリックしたときは ▶ をクリックしたときと違って、その年の一覧ページに飛びます。
「東京」というカテゴリーは実際にはありませんので、▶ をクリックしたときと同じ動作をするようにしてみました。
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script> (function($) { $(function() { var re = /【(.*)】.*\((.*)\)/; var forEach = Array.prototype.forEach; var cat_name_map = {}; forEach.call(document.querySelectorAll("div.hatena-module-category ul.hatena-urllist li a"), function(a) { var match = re.exec(a.textContent); if (match) { var cat = match[1]; var ar = cat_name_map[cat]; if (! ar) { ar = [0, 0]; } ar[0] += 1; ar[1] += parseInt(match[2]); cat_name_map[cat] = ar; } }); var cat_node_map = {}; forEach.call(document.querySelectorAll("div.hatena-module-category ul.hatena-urllist li a"), function(a) { var match = re.exec(a.textContent); if (match) { var cat = match[1]; if (cat_name_map[cat][0] > 1) { var original_item = a.parentNode; var new_item = document.createElement("LI"); new_item.innerHTML = original_item.innerHTML; new_item.style.paddingLeft = "2em"; var sub_category_list = cat_node_map[ cat ]; if (! sub_category_list) { /* LI : original_item | V LI : sub_category_parent SPAN : arrow SPAN : label UL : sub_category_list LI : new_item */ var sub_category_parent = document.createElement("LI"); original_item.parentNode.insertBefore(sub_category_parent, original_item); var arrow = document.createElement("SPAN"); arrow.innerHTML = "▶"; arrow.style.marginRight = "0.5ex"; arrow.style.cursor = "pointer"; arrow.onclick = function() { var sub_category_list = this.nextSibling.nextSibling; if (sub_category_list.style.display == "none") { this.innerHTML = "▼"; sub_category_list.style.display = ""; } else { this.innerHTML = "▶"; sub_category_list.style.display = "none"; } }; sub_category_parent.appendChild(arrow); var label = document.createElement("SPAN"); label.innerHTML = cat + " (" + cat_name_map[cat][1] + ")"; label.style.textDecoration = "underline"; label.style.color = "#0E4B84"; label.style.cursor = "pointer"; label.onclick = function() { this.previousSibling.onclick(); }; sub_category_parent.appendChild(label); sub_category_list = document.createElement("UL"); sub_category_list.style.display = "none"; sub_category_parent.appendChild(sub_category_list); cat_node_map[ cat ] = sub_category_list; } sub_category_list.appendChild(new_item); original_item.parentNode.removeChild(original_item); } } }); }); })(jQuery); </script>
以下のコードを、「デザイン」の「ヘッダ」の「タイトル下」のところにペタッと。
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script> (function($) { $(function() { var re = /【(.*)】.*\((.*)\)/; var forEach = Array.prototype.forEach; var cat_name_map = {}; forEach.call(document.querySelectorAll("div.hatena-module-category ul.hatena-urllist li a"), function(a) { var match = re.exec(a.textContent); if (match) { var cat = match[1]; var ar = cat_name_map[cat]; if (! ar) { ar = [0, 0]; } ar[0] += 1; ar[1] += parseInt(match[2]); cat_name_map[cat] = ar; } }); var cat_node_map = {}; forEach.call(document.querySelectorAll("div.hatena-module-category ul.hatena-urllist li a"), function(a) { var match = re.exec(a.textContent); if (match) { var cat = match[1]; if (cat_name_map[cat][0] > 1) { var original_item = a.parentNode; var new_item = document.createElement("LI"); new_item.innerHTML = original_item.innerHTML; new_item.style.paddingLeft = "2em"; var sub_category_list = cat_node_map[ cat ]; if (! sub_category_list) { /* LI : original_item | V LI : sub_category_parent SPAN : arrow SPAN : label UL : sub_category_list LI : new_item */ var sub_category_parent = document.createElement("LI"); original_item.parentNode.insertBefore(sub_category_parent, original_item); var arrow = document.createElement("SPAN"); arrow.innerHTML = "▶"; arrow.style.cursor = "pointer"; arrow.onclick = function() { var sub_category_list = this.nextSibling.nextSibling; if (sub_category_list.style.display == "none") { this.innerHTML = "▼"; sub_category_list.style.display = ""; } else { this.innerHTML = "▶"; sub_category_list.style.display = "none"; } }; sub_category_parent.appendChild(arrow); var label = document.createElement("SPAN"); label.innerHTML = cat + " (" + cat_name_map[cat][1] + ")"; sub_category_parent.appendChild(label); sub_category_list = document.createElement("UL"); sub_category_list.style.display = "none"; sub_category_parent.appendChild(sub_category_list); cat_node_map[ cat ] = sub_category_list; } sub_category_list.appendChild(new_item); original_item.parentNode.removeChild(original_item); } } }); }); })(jQuery); </script>
サブカテゴリは、【】でくくられたものを拾ってます。
サブカテゴリのカテゴリ数がひとつだけの場合には、折りたたむ意味がないので、そのまま表示するようにしました。
クリックできるのは、ちょっと狭いかなという気もしますが、三角のところだけにしてます。
・回答には、実装結果を確認できるはてなブログURLが必須です。
カテゴリのデータを作るのが大変面なので、id:thyself2005 さんのはてなブログで、Bookmarklet として動作確認しました。
こういう感じになります。
1.今後【】でくくる複数のカテゴリを追加する場合、特に追加作業等発生せずそれらもサブカテゴリ化できるということでしょうか?
【】でくくられた文字を親カテゴリだと判断するようにしてますので、カテゴリが追加された場合には それに追従します。
2.カテゴリのクリックできる範囲と見た目を月別アーカイブの体裁に揃えることはできますか?
※例えば「? 東京 (XXX)」だと東京 (XXX)も青緑色の下線リンクとなっており、▶ と東京の間の間隔が半角スペース1個分くらい空いている感じです。
月別アーカイブの見た目に寄せることはできますが、月別アーカイブの場合には「年」をクリックしたときは ▶ をクリックしたときと違って、その年の一覧ページに飛びます。
「東京」というカテゴリーは実際にはありませんので、▶ をクリックしたときと同じ動作をするようにしてみました。
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script> (function($) { $(function() { var re = /【(.*)】.*\((.*)\)/; var forEach = Array.prototype.forEach; var cat_name_map = {}; forEach.call(document.querySelectorAll("div.hatena-module-category ul.hatena-urllist li a"), function(a) { var match = re.exec(a.textContent); if (match) { var cat = match[1]; var ar = cat_name_map[cat]; if (! ar) { ar = [0, 0]; } ar[0] += 1; ar[1] += parseInt(match[2]); cat_name_map[cat] = ar; } }); var cat_node_map = {}; forEach.call(document.querySelectorAll("div.hatena-module-category ul.hatena-urllist li a"), function(a) { var match = re.exec(a.textContent); if (match) { var cat = match[1]; if (cat_name_map[cat][0] > 1) { var original_item = a.parentNode; var new_item = document.createElement("LI"); new_item.innerHTML = original_item.innerHTML; new_item.style.paddingLeft = "2em"; var sub_category_list = cat_node_map[ cat ]; if (! sub_category_list) { /* LI : original_item | V LI : sub_category_parent SPAN : arrow SPAN : label UL : sub_category_list LI : new_item */ var sub_category_parent = document.createElement("LI"); original_item.parentNode.insertBefore(sub_category_parent, original_item); var arrow = document.createElement("SPAN"); arrow.innerHTML = "▶"; arrow.style.marginRight = "0.5ex"; arrow.style.cursor = "pointer"; arrow.onclick = function() { var sub_category_list = this.nextSibling.nextSibling; if (sub_category_list.style.display == "none") { this.innerHTML = "▼"; sub_category_list.style.display = ""; } else { this.innerHTML = "▶"; sub_category_list.style.display = "none"; } }; sub_category_parent.appendChild(arrow); var label = document.createElement("SPAN"); label.innerHTML = cat + " (" + cat_name_map[cat][1] + ")"; label.style.textDecoration = "underline"; label.style.color = "#0E4B84"; label.style.cursor = "pointer"; label.onclick = function() { this.previousSibling.onclick(); }; sub_category_parent.appendChild(label); sub_category_list = document.createElement("UL"); sub_category_list.style.display = "none"; sub_category_parent.appendChild(sub_category_list); cat_node_map[ cat ] = sub_category_list; } sub_category_list.appendChild(new_item); original_item.parentNode.removeChild(original_item); } } }); }); })(jQuery); </script>
サブカテゴリの行間が空いてて、ちょっと間延びしますね。
月別アーカイブに合わせて、追記の回答の 30行目付近に paddingBottom の指定を入れた方がすっきりします。
var new_item = document.createElement("LI"); new_item.innerHTML = original_item.innerHTML; new_item.style.paddingLeft = "2em"; new_item.style.paddingBottom = 0; // ★これを追加 var sub_category_list = cat_node_map[ cat ]; if (! sub_category_list) {
ご回答&補足ありがとうございます。
ぽけっとしすてむさんの回答含め導入を検討しますが、導入が簡単な点、追記サポート(サブカテゴリの行間調整)も助かりそうなので、今回ベストアンサーといたします。
※再掲
以下のコードをHTMLが挿入できる任意の場所に挿入します。
※記事内のみ表示される場所に貼り付けると、それ以外のページでは通常通りの表示になります。
<script> (function(H,T,N,p,s,n,e){H.Htnpsne=H.Htnpsne||{};Htnpsne[s]=Htnpsne[s]||function(){(Htnpsne[s].q=Htnpsne[s].q||[]).push(arguments)};n=T.createElement(N);e=T.getElementsByTagName(N)[0];n.async=1;n.src=p;e.parentNode.insertBefore(n,e)})(window,document,"script","//niyari.github.io/hatenablog-modules/hb-subcat.min.js","SubCategory"); Htnpsne.SubCategory('setting', { 'pattern': '【(.+)】' }); </script>
サブカテゴリについては質問のとおりになるよう、【(親カテゴリ名)】となるように設定してありますが、
Htnpsne.SubCategory('setting', { 'pattern': '【(.+)】' });
こちらの部分を変更する事で任意の文字列で親カテゴリ、サブカテゴリを生成する事ができます。
/* 例:「親カテゴリ → サブカテゴリ」 という区切りの場合*/ Htnpsne.SubCategory('setting', { 'pattern': '(.+) → ' });
あまり例は無いと思いますが、複数のカテゴリーモジュールが設置されている場合でも動作するようになっています。
回答には、実装結果を確認できるはてなブログURLが必須です
動作確認用のはてなブログがありますが、プライベート利用の為、スクリーンショットにて回答とさせて頂きます。
こちらをデザインCSS、または
<style> ... </style>
このようにstyleタグで囲んでHTMLとして貼り付けると利用できます。
4.(略)地域別、料理ジャンルとか複数に分けてそれぞれの配下に指定したカテゴリ・サブカテゴリが表示できれば(後略)
カテゴリ生成時に、関連したクラスを出力していますので、それに合わせて追加のスクリプトとCSSにて対応できるかと思います。
class="hatena-module hatena-module-category"
class="hatena-module-title"
表示されるカテゴリのタイトル
(こちらのタイトル部分を利用)
例えば、上記のタイトル部分を取得して、表示・非表示のクラスを指定する事で実現できるかと思います。
※別機能になりますので、この回答では対応しません。
ご回答ありがとうございます。
a-kuma3さんの回答含め導入を検討します。
取り急ぎ、本質問は終了とします。
サブカテゴリの行間が空いてて、ちょっと間延びしますね。
2015/12/08 17:48:33月別アーカイブに合わせて、追記の回答の 30行目付近に paddingBottom の指定を入れた方がすっきりします。
ご回答&補足ありがとうございます。
2015/12/12 10:41:39ぽけっとしすてむさんの回答含め導入を検討しますが、導入が簡単な点、追記サポート(サブカテゴリの行間調整)も助かりそうなので、今回ベストアンサーといたします。