JavaScriptで目次を自動生成する

FAQコーナーみたいなコンテンツを作っていて、内容は整備されてきたけど、目次も作らなきゃ、というときの話。

FAQの一問ずつは、h2タグで見出し、pタグで内容、といった感じだったとする。下みたいな。

<h2>質問1です。云々</h2>
<p>それへの回答は云々。</p>

<h2>質問2です。云々</h2>
<p>それへの回答は云々。</p>

ドキュメントの中のすべてのh2タグを集めて、それぞれその直前にリンク用のアンカータグを作って埋め込み、ページの初めにはそこへジャンプするaタグをリスト状に並べればいいわけだから…というわけで、下のようなコードを書いた。うまくいった。

// TOC auto generator
var generate_toc = function() {
  // 目次投入場所
  var toc = document.getElementById('toc');
  // 見出しを集める
  var headings = document.getElementsByTagName('h2');
  cn = [];
  cn.push('<ul>');
  for (var i=0;i<headings.length;i++) {
    var h = headings[i];
    // アンカータグを作って
    var d = document.createElement('a');
    var aname = 'a'+i;
    d.name = aname;
    // 各h2タグの直前に突っ込む
    h.parentNode.insertBefore(d, h);
    // 目次からそのアンカーにリンクを張る
    var s = '<li><a href="#' + aname + '">'+h.innerHTML+'</a></li>';
    cn.push(s);
  }
  cn.push('</ul>');
  toc.innerHTML = cn.join("");
}
generate_toc();

目次を表示させたい場所には、id=toc の空のdivタグを置いておくこと。generate_tocを呼び出すのは、bodyのロードイベントを捕まえて行うほうが多分適切。まあ、ページの終わりで呼び出してもちゃんと動くようだけど。