2019/05/03

FC2ブログに目次を表示できるようにしました。その設定方法等です。

ブログに目次が欲しいなぁ。と思ったのですが、FC2ブログではその機能が提供されていませんでした。※見つけられてないだけかもしれませんが。。

なので、自分で作ってみることにしました。※同じようなことをしてくれるJavaScriptのプラグインとかあるようですが、勉強のため自分で作りました。

20190503目次1

作成したJavaScript、CSSの記載方法や、テンプレートなどの設定方法を書きます。

※選択しているテンプレートや、別のJavaScriptと干渉してうまく動かない可能性もあります。この手順を実施される場合は、自己責任でお願いします。また、テンプレートを触りますので、必ずテンプレートのバックアップをとってから作業してください。

目次のメリットは?

記事の最初のほうに目次があると、最後まで読まなくても、記事の全体感がわかります。また、目次をクリックすると、直接その場所に遷移できるのもいいですね。

実際、他のサイトを見ているときに、目次があるとわかりやすいなぁ。と思っていました。

どのような目次を作成するの?

下記のような仕様の目次を作ってみたいと思います。
目次は自動生成させる

先にも書きましたが、FC2ブログには目次を自動生成する機能はないので、自分で作ります。

管理画面の記事作成では生成できないので、JavaScriptを使用して、ブラウザ側で記事を見たときに自動生成し、表示されるようにします。

JavaScriptのプログラム記載量を減らすために、jQueryを使用します。※jQueryはJavaScriptの記載を少し簡単にしてくれるものです。

hタグのタイトルを取得する

プログラムで取得する以上、ルールを設定する必要があるため、hタグのタイトルを目次の対象とします。

h1タグは、ブログ名や、記事のタイトルに使われているので、h2~h6のタグを対象とします。

※制約として、h2タグの次に、h3タグがなく、いきなりh4タグを記載するといったパターンには対応しません。頑張れば対応できると思いますが、その分処理時間もかかるため、イレギュラーなパターンは想定外とします。

ページ内リンクを設定(アンカーを設定)

目次内のタイトルをクリックすると、該当のhタグまで遷移するようにします。

自分で表示位置を指定できる

記事によって表示位置を変更したいこともあると思うので、特定のタグを記載した個所に表示されるようにします。

また、記事によっては、目次が不要な記事もあると思うので、特定のタグが記載されていない場合は、表示されないようにします。

トップページでも大丈夫

トップページでは最新の記事がいくつか並んで表示されますが、すべての記事のhタグが各記事内に表示されないように、記事単位で処理されるようにします。

目次の作成の流れ

下記のような流れで作成します。

  1. jQueryをテンプレートに設定する
  2. テンプレート内に記事のIDを設定する
  3. 目次作成用のJavaScriptをテンプレートに設置する
  4. 目次作成用のCSSを設定する
  5. 記事に目次作成用のタグを書き込む

目次の設定方法

では実際に目次を設置していきます。

jQueryをテンプレートに設定する

※すでにjQueryを読み込むようにしている場合はここは対応不要です。

※テンプレートを修正する場合、万が一のため、「複製」をクリックして現状のテンプレートのバックアップをとってから作業することをお勧めします。

まずは、ブログの管理画面を開き、左メニュー内の「設定」>「テンプレート」をクリックします。

画面右側を少し下に行くと、【[ テンプレート名 ] のHTML編集】があります。そのheadタグ内に下記の記載をします。
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script></p>

※headタグ内であれば、とりあえずどこでもいいのですが、私は下記のようにstylesheetを読み込む下に記載しました。
<link rel="stylesheet" href="<%css_link>">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>

記載後は必ずプレビューをクリックして、問題ないことを確認してから、更新ボタンをクリックしてください。

テンプレート内に記事のIDを設定する

トップページや、カテゴリ一覧などで、複数の記事が表示される場合に記事を区別できるようにテンプレートを修正します。

上の手順でテンプレートの修正画面へ遷移し、「<!--topentry-->」が記載されている個所を探します。「<!--topentry-->」の直下のタグに「id="entry_id<%topentry_no>"」を追加します。
※すでにid=xxxxの記載がある場合は、それを書き換えます。
※私の場合、すでにidの記載があったので、下記のように修正しました。

20190503目次2

目次作成用のJavaScriptを設置する

下記のJavaScriptをテンプレート内の下のほうにある</body>の上に記載してください。

<script type="text/javascript">
function get_index(target,index){
	let id_cnt=1,id_str,index_str="",target_tag,n_level="",b_level="",o_tag,i,tmp_str;
	target_tag =  "h2,h3,h4,h5,h6";
	target.find(target_tag).each(function(){
		if($(this).attr("id") == undefined){
			id_str = "index_"+index+"_" + id_cnt;
			$(this).attr("id",id_str);
			id_cnt++;
		}else{
			id_str = $(this).attr("id");
		}

		tmp_str = '<a href="#'+id_str+'">' + $(this).text() + '</a>';
		n_level = $(this).prop("tagName").substr(1,1);
		if(n_level > b_level){
			index_str += "<ol><li>"+tmp_str;
		}else if(n_level < b_level){
			for(i=0;i<(b_level - n_level);i++){
				index_str += "</li></ol>";
			}
			index_str += "</li><li>"+tmp_str;
		}else{
			index_str += "</li><li>"+tmp_str;
		}
		b_level = n_level;
	});
	for(i=0;i<(b_level - n_level);i++){
		index_str += "</li></ol>";
	}
	index_str += "</li></ol>";

	return index_str;
}
$(function(){
	let entry_id;
	$('[id^="entry_id"]').each(function(index){
		let index_head='<p> 目次 </p>';
		entry_id= $(this).attr("id");
		$("#"+entry_id+" .nknot_index_area").html(index_head+get_index($(this),index));
	});
</script>

※文字色が青の箇所は変更することができますが、後で記載する、cssおよび、記事へ目次を表示するタグの記載も合わせて同じ文字で変更する必要があります。

※h2~h6を対象にしていますが、変更したい場合は、「target_tag=」の箇所で対象としたいタグに変更してください。ただ、稼働テストはh3までしかやっていません。

※hタグに遷移するためidを設定するようにしていますが、すでにidが設定されている場合は、値を変更しないようにしているので安心してください。

目次作成用のCSSを設定する

テンプレートの編集の下のほうに【[ テンプレート名 ] のスタイルシート編集】という箇所があります。 その中を一番下までスクロールし、下記を追加します。

.nknot_index_area{
    border: 1px solid;
    margin: 30px;
    padding: 10px;
    background: #f0f8ff;
    line-height: 1.3em;
}
.nknot_index_area p {
    text-align: center;
    font-size: 1.2em;
}
.nknot_index_area  ol{
  counter-reset: cnt;
  padding-left: 0;
}
.nknot_index_area  ol li{
  list-style: none;
  margin-bottom: 8px;
}
.nknot_index_area  ol li::before{
  content: counters(cnt, ".") ". ";
  counter-increment: cnt;
}
.nknot_index_area  ol ol{
  counter-reset: cnt;
  margin-left: 20px;
  margin-top: 8px;
  margin-bottom: 0;
}
ol.nknot_index_area, ol.nknot_index_area ol, ol.nknot_index_area ol ol, ol.nknot_index_area ol ol ol, ol.nknot_index_area ol ol ol ol{
  padding-left: 1em;
}

※JavaScriptで青文字の文字を変更した方は同じ文字で変更してください。

※背景色を変えたい方は「.nknot_index_area」内の「background」を変更してください。※色の数字はGoogleでカラーコードなどで検索し、好きなコードを取得すれば大丈夫です。

記事に目次作成用のタグを書き込む

ここまでで、目次が作成される準備が整いましたので、最後に各記事内に目次を表示するタグを記載します。
目次を表示したい箇所に「<div class="nknot_index_area"></div>」を書いてください。
私の場合、下記のように記載しました。反映した実際の記事はここです。

20190503目次3

※JavaScriptで青文字の文字を変更した方は同じ文字で変更してください。

※私の記事はタグがいっぱい書かれていますが、hタグさえあれば動くはずです。

※記事の編集画面直下にある、リアルタイムプレビューには表示されません。プレビューボタンでは表示されます。

関連記事