JavaScriptで自動目次を生成する方法

JavaScriptで自動目次を生成する方法
JavaScript学習におすすめの書籍

Amazonの読み放題サービスKindle Unlimited無料体験キャンペーン実施中!

Amazon Kindle Unlimited 公式

ブログ記事が長くなると、読者にとって記事内のどこに何が書かれているのかを把握するのが難しくなります。そんな時、目次を設置することで、読者はすぐに見たい情報にアクセスできるようになります。この記事では、JavaScriptを使って自動的に目次を生成する方法を2つ紹介します。1つ目はh2タグのみを対象にしたシンプルな方法、2つ目はh2タグとh3タグを取得して階層構造を持たせる方法です。

h2タグのみを対象にした目次の生成

まずは、記事内のh2タグのみを対象にして目次を生成する方法を紹介します。この方法では、記事内のh2見出しをすべてリストアップし、クリックするとその見出しにジャンプできるリンク付きの目次を生成します。

JavaScript
// 自動目次生成
let tocContainer = document.querySelector('.toc-container');  // 目次を表示するコンテナ
if (!tocContainer) {
	tocContainer = document.querySelector('#toc');  // 目次を表示する別のコンテナ
}
if (tocContainer) {
	let contentWrapper = document.querySelector('.content-wrapper');  // 記事本文を囲んでいるラッパー
	let h2Tags = contentWrapper.querySelectorAll('h2');  // 記事内のH2タグを全て取得
	if (h2Tags.length > 1) {
		let tocList = document.createElement("ol");
		let listItems = "";
		for (let i = 0; i < h2Tags.length; i++) {
			let heading = h2Tags[i];
			let headingText = heading.innerHTML.trim(); // h2タグ内のHTMLを取得
			let tempDiv = document.createElement('div');
			tempDiv.innerHTML = headingText;
			headingText = tempDiv.textContent || tempDiv.innerText || ""; // HTMLタグを削除したテキストを取得
			heading.setAttribute('id', "heading_id" + i);  // リンクで飛べるようにIDをつける
			listItems += '<li><a href="#heading_id' + i + '">' + headingText + '</a></li>';
		}
		tocList.innerHTML = listItems;
		tocContainer.appendChild(tocList);
	} else {
		tocContainer.style.display = "none";
	}
}

このコードでは、まず目次を表示するためのコンテナを取得します。次に、記事本文を囲んでいるラッパーからすべてのh2タグを取得し、それぞれにIDを付与します。最後に、取得したh2タグのテキストを目次リストとしてコンテナに追加します。

h2タグとh3タグを対象にした階層構造の目次生成

次に、記事内のh2タグとh3タグを取得し、h3タグを対応するh2タグの目次項目の下にネストする方法を紹介します。

JavaScript
// 自動目次生成
let tocContainer = document.querySelector('.toc-container');  // 目次を表示するコンテナ
if (!tocContainer) {
	tocContainer = document.querySelector('#toc');  // 目次を表示する別のコンテナ
}
if (tocContainer) {
	let contentWrapper = document.querySelector('.content-wrapper');  // 記事本文を囲んでいるラッパー
	let headings = contentWrapper.querySelectorAll('h2, h3');  // 記事内のH2タグとH3タグを全て取得
	if (headings.length > 1) {
		let tocList = document.createElement("ol");
		let listItems = "";
		let currentSubList = null;  // h3タグの目次項目を格納するul要素
		for (let i = 0; i < headings.length; i++) {
			let heading = headings[i];
			let headingText = heading.innerHTML.trim(); // h2タグまたはh3タグ内のHTMLを取得
			let tempDiv = document.createElement('div');
			tempDiv.innerHTML = headingText;
			headingText = tempDiv.textContent || tempDiv.innerText || ""; // HTMLタグを削除したテキストを取得
			heading.setAttribute('id', "heading_id" + i);  // リンクで飛べるようにIDをつける

			if (heading.tagName.toLowerCase() === 'h2') {
				// h2タグの場合、新しいli要素を作成し、ulを閉じる
				if (currentSubList) {
					listItems += currentSubList.outerHTML;
					currentSubList = null;
				}
				listItems += '<li><a href="#heading_id' + i + '">' + headingText + '</a></li>';
			} else if (heading.tagName.toLowerCase() === 'h3') {
				// h3タグの場合、現在のli要素の中にulを作成
				if (!currentSubList) {
					currentSubList = document.createElement('ul');
				}
				currentSubList.innerHTML += '<li><a href="#heading_id' + i + '">' + headingText + '</a></li>';
			}
		}
		// 最後に残っているulをリストに追加
		if (currentSubList) {
			listItems += currentSubList.outerHTML;
		}
		tocList.innerHTML = listItems;
		tocContainer.appendChild(tocList);
	} else {
		tocContainer.style.display = "none";
	}
}

このコードでは、h2タグとh3タグの両方を取得し、各見出しにIDを付与します。h3タグが見つかった場合、それをulタグで囲んで対応するh2タグの下にネストします。

まとめ

この記事では、JavaScriptを使って自動的に目次を生成する2つの方法を紹介しました。シンプルにh2タグのみを対象にする方法と、h2タグとh3タグを階層構造で目次に含める方法です。どちらの方法も、読者にとって記事をより読みやすく、ナビゲートしやすくするための有効な手段です。目的や記事の構造に応じて、適切な方法を選んで実装してみてください。

制作のご相談・ご依頼はこちらから!

Author

WARACRO(ワラクロ)

2018年に起業し、Webデザイナー・WebディレクターとしてWordPress案件を中心にWeb制作のお仕事をしています。
このブログでは、Webサイト制作に関する情報をお届けしています。

Webデザイン学習におすすめの講座
To Top