技術的な話題    trashbox /


目次機能が出来るプラグインとかってあるけど、別に自分で作ってもいいよねって思ったので作った。そのうちモリモリっとテーマやプラグインの整備に力を入れていくので、そのあたりに介入されると困るので~~ってくらいの理由で作った次第。

これこれ!この目次! h2 タグを使うんだよ

2階層までなら対応するよ! h3 タグだよ

ここは h3 タグ

ここは h2 タグなので 1 階層目になる

ここは 2 階層。 h3 タグだからね

デモおわり

ここまで見出しだらけで見にくいのは仕方ない。

仕組み

  1. h2 タグと h3 タグを投稿箇所から探す
  2. それぞれのタグに ID をつける
  3. それぞれへのリンクを生成する
  4. 目次用の HTML を作る
  5. 一番最初の見出しの直前に HTML を挿入する

タイトルこそ WordPress って言ってるけど JavaScript が差し込めるブログサービス的なものなら、投稿箇所を探す部分を調整する必要はあるけど、どれでもできるんじゃないかな。
jQuery を使わなくていいように作ったので jQuery ないんだけど、みたいな環境でもいいと思う。いやそもそもそういう環境はまた違う問題っぽいけど…。

JavaScript

(function() {
	setTimeout(function() {
		var headingIndex = 1;
		Array.prototype.forEach.call(document.querySelectorAll('.post_content'), function(postContent) {
			if (postContent.innerText.length < 100) {
				return;
			}

			var headings = postContent.querySelectorAll('h2,h3');
			if (headings.length <= 0) {
				return;
			}

			var indexHtml = '
    '; var lastElement = 'H2'; Array.prototype.forEach.call(headings, function(e) { var id = 'heading-' + headingIndex; e.id = id; if (lastElement != e.tagName) { if (lastElement == 'H2') { indexHtml += '
      '; } else { indexHtml += '
    '; } lastElement = e.tagName; } indexHtml += '
  • ' + e.innerHTML + '
  • '; headingIndex++; }); indexHtml += '
'; var wrapper = document.createElement('div'); wrapper.classList.add('content-index'); wrapper.innerHTML = indexHtml; headings[0].parentNode.insertBefore(wrapper, headings[0]); }); if (location.hash.length > 1) { setTimeout(function() { var element = document.querySelector(location.hash); if (element != null) { window.scroll(0, element.offsetTop); } }, 10); } }, 10); })();

CSS

.post_content .content-index {
	border: 2px solid #eee;
	border-radius: 20px;
	padding: 20px;
	background-color: #fefefe;
}

.post_content .content-index:before {
	content: '目次';
	display: block;
	font-size: 24.5px;
	margin-bottom: 15px;
}

他のスタイルとのバッティング回避した部分を除くとこれだけ。シンプルに線を引くことと色味の調整くらい。

SEO的な観点とか

目次足すと SEO に効果あるのかわからんけど、ふつうに見ていて、長めの投稿だったら合ったほうが便利だよね、とは感じる。

一応 Fetch as Google をして Google Bot にこの目次が認識されていることは確認したので、まあいいんじゃないかな。