序章
この記事は「そうだ!Bloggerの記事に目次を付けよう!」から始まる一連の「Bloggerの記事に目次をJavaScriptで自動的に付与する」シリーズの構成記事です。(2nd シリーズ)記事一覧は「Bloggerの記事に目次をJavaScriptで自動的に付与する - サポートページ」よりどうぞ。
2nd シリーズでは、1st シリーズで作成した目次機能に基本的な機能追加を行います。
今回の目的
2nd シリーズで機能追加を行った目次自動生成プログラムとスタイルシートの配布を行います。スタイルシート
#auto-generated-index_title { border-style:solid; border-width:1px; border-color:#999999; background-color:#eeeeee; font-weight:bold; margin:10px 100px 0px 20px; } #auto-generated-index_content { border-style:solid; border-width:1px; border-color:#999999; background-color:#ffffff; font-weight:normal; margin:0px 100px 20px 20px; } #auto-generated-index_content_h1 { text-indent:1em; } #auto-generated-index_content_h2 { text-indent:2em; } #auto-generated-index_content_h3 { text-indent:3em; } #auto-generated-index_content_h4 { text-indent:4em; } #auto-generated-index_content_h5 { text-indent:5em; } #auto-generated-index_content_h6 { text-indent:6em; } #auto-generated-index_help { float:right; font-weight:bold; border-width:1px; border-style:solid; width:1em; text-align:center; }
ソースコード
/* 生成処理制御パラメータ */ var min_auto_generated_index_items = 2; /* 見出しの数がこの数以上になった場合に見出しを挿入する */ /* 目次挿入先要素の id の正規表現 */ var regExp_id_obj_insert_index = new RegExp("^post-body-"); /* 見出し内のタグを削除して目次として使用するかどうか */ var use_headline_htmlTag = false; /* 目次のタイトル */ var index_title = "- INDEX -"; /* ページ読み込み時に目次の生成・挿入処理を実行 */ generateIndex(); /* 目次の生成・挿入処理 */ function generateIndex() { /* 投稿本文が格納されている div 要素を発見し、目次を挿入する */ var divs = document.getElementsByTagName("div"); for (var i = 0; i < divs.length; i++) { if (regExp_id_obj_insert_index.test(divs[i].id)) { /* 投稿本文が格納されている div 要素発見時の処理 */ generateIndexForObj(divs[i]); break; } } } /* 目次の生成・挿入処理 obj : 目次の挿入先 */ function generateIndexForObj(obj) { /* 目次として使用する見出しの一覧のHTML */ var html_item = ""; /* 見出しの数 */ var item_count = 0; /* 再帰的に見出しを検索し、目次の HTML を作成する */ generateIndexHTMLRecursive(obj); function generateIndexHTMLRecursive(obj) { /* 見出しの列挙 */ for ( var i = 0; i < obj.childNodes.length; i++ ) { /* 見出しタグの場合、見出しのレベルに応じて書式を設定して記録する */ var originalTagName = obj.childNodes[i].tagName; if ( originalTagName !== void 0 ) { /* void 0 = undefined なので、originalTagName が undefined でなければ処理する */ var tagName = originalTagName.toLowerCase(); if ( tagName.lastIndexOf("h", 0) == 0 ) { /* アンカー設定 すでに id が設定されている場合は、その id をアンカーに用いる */ if ( obj.childNodes[i].id == "" ) { obj.childNodes[i].id = "auto-generated-index_target" + item_count; } /* 見出しの内容 */ var headline = obj.childNodes[i].innerHTML; if (!use_headline_htmlTag) { /* 見出し内の HTMLタグを使用しない場合には、HTML タグを削除する */ headline = headline.replace(/<[^>]*>/g, ""); } var level = Number(tagName.substr(1, tagName.length - 1)); /* タグ hx の x の取り出し */ html_item += "<div id=\"auto-generated-index_content_h" + level + "\"><a href=\"#" + obj.childNodes[i].id + "\">" + headline + "</a></div>\r\n"; item_count++; } } /* 子ノードに対して再帰的に再帰的に見出しを検索 */ generateIndexHTMLRecursive(obj.childNodes[i]); } } /* 目次のHTML */ var html_index = ""; if ( item_count >= min_auto_generated_index_items ) { html_index = "<div id=\"auto-generated-index\"><div id=\"auto-generated-index_title\">" + index_title + "<span id=\"auto-generated-index_help\"><a href=\"http://upa-pc.blogspot.jp/p/addindex.html\" title=\"この目次について\" rel=\"nofollow\">?</a></span></div><div id=\"auto-generated-index_content\">" + html_item + "</div></div>"; /* 本文に目次を挿入 */ obj.innerHTML = html_index + obj.innerHTML; } }
ソースコード(最適化後)
var min_auto_generated_index_items=2,regExp_id_obj_insert_index=/^post-body-/,use_headline_htmlTag=!1,index_title="目次";generateIndex();function generateIndex(){for(var a=document.getElementsByTagName("div"),c=0;c<a.length;c++)if(regExp_id_obj_insert_index.test(a[c].id)){generateIndexForObj(a[c]);break}} function generateIndexForObj(a){function c(a){for(var b=0;b<a.childNodes.length;b++){var d=a.childNodes[b].tagName;if(void 0!==d){var e=d.toLowerCase();0==e.lastIndexOf("h",0)&&(""==a.childNodes[b].id&&(a.childNodes[b].id="auto-generated-index_target"+f),d=a.childNodes[b].innerHTML,use_headline_htmlTag||(d=d.replace(/<[^>]*>/g,"")),e=Number(e.substr(1,e.length-1)),g+='<div id="auto-generated-index_content_h'+e+'"><a href="#'+a.childNodes[b].id+'">'+d+"</a></div>\r\n",f++)}c(a.childNodes[b])}}var g= "",f=0;c(a);var h="";f>=min_auto_generated_index_items&&(h='<div id="auto-generated-index"><div id="auto-generated-index_title">'+index_title+'<span id="auto-generated-index_help"><a href="http://upa-pc.blogspot.jp/p/addindex.html" title="この目次について" rel="nofollow">?</a></span></div><div id="auto-generated-index_content">'+g+"</div></div>",a.innerHTML=h+a.innerHTML)};
補足:Blogger に設置する場合
投稿ページにのみ目次を表示するためと、HTMLテンプレートの修正にて正常にJavaScriptコードを埋め込むために、<!-- 目次の自動生成 START -->
<b:if cond='data:blog.pageType == "item"'>
<!-- 投稿ページにのみ目次を表示する -->
<script type='text/javascript'>
//<![CDATA[
<!--
と
//-->
//]]>
</script>
</b:if>
<!-- 目次の自動生成 END -->
の間にソースコードを記載しています。
修正
2014/12/17
- "この目次について"のリンクに rel="nofollow" を追加
「Bloggerの記事に目次をJavaScriptで自動的に付与する」シリーズ 記事一覧へ
コメントを投稿
コメント投稿機能について