当記事ではJavascriptを使用して見出しから目次を自動生成する方法について記します。
複数階層の見出しにも対応しています。
やりたいこと
下記のようなHTMLがある時に、Javascriptを使用して、見出しから目次を自動生成する事を目指します。
目次が挿入される場所は一番最初の見出しタグの前とします。
<h1>タイトル</h1>
<div id="content">
<h2>見出し1</h2>
<h3>小見出し1</h3>
<h3>小見出し2</h3>
<h4>小小見出し1</h4>
<h5>小小小見出し1</h5>
<h3>小見出し3</h3>
<h2>見出し2</h2>
<h3>小見出し1</h3>
</div>
目次を自動生成するスクリプト
見出しから目次を自動生成するJavascriptは下記になります。
目次から見出しへ飛べるようにアンカーリンクも付けてくれます。
const toc = '<div id="toc"><p>目次</p><ul></ul></div>' // 目次の骨組みを定義
const target = '#content h2, #content h3, #content h4, #content h5' // 対象の見出し要素を指定
document.querySelector(target).insertAdjacentHTML('beforebegin', toc) // 骨組みをDOMに追加
document.querySelectorAll(target).forEach((h, i) => {
const id = `toc-${i}` // アンカーリンク用のID
const text = h.textContent // 目次のテキスト
const attr = `class="toc-${h.tagName}"` // 目次タグの属性
const list = `<li ${attr}><a href='#${id}'>${text}</a></li>` // 目次リスト(リンク付き)
document.querySelector('#toc ul').innerHTML += list // 目次リストを追加
h.setAttribute('id', id) // 見出しにIDを付与(アンカーリンク用)
})
下記のような目次が出力されます。
次は見た目を整えて階層をわかりやすくしてみましょう。
見た目を整えて階層をわかりやすくする
あとは見た目をよしなに整えるだけです。CSSのサンプルを載せておきます。
Javascriptが目次のリスト要素にtoc-H3などのクラスを付けてくれてるので階層をわかりやすくできます。
#toc .toc-H3 { margin-left: 15px }
#toc .toc-H4 { margin-left: 30px }
#toc .toc-H5 { margin-left: 45px }
#toc .toc-H6 { margin-left: 60px }
#toc {
border: 3px #BDBDBD solid;
padding: 30px;
margin: 50px 0;
}
#toc p {
font-weight: bold;
font-size: 24px;
margin-bottom: 10px;
}
#toc a{
font-size: 16px;
color: inherit;
}
#toc ul {
padding-left: 20px;
}
#toc li {
line-height: 1.8;
}
階層がわかりやすくなりました。
h2だけ目次にする
先ほどはh2からh5までを目次にしました。
どの見出しレベルまで目次にするかは、Javascriptの下記の部分で定義していますのでよしなに変更してください。
const target = '#content h2, #content h3, #content h4, #content h5'
例えば、以下のように変更するとh2のみ目次にすることができます。
const target = '#content h2'
以上、Javascriptで見出しから目次を自動生成する方法でした!