
WordPressの投稿ページで、H2やH3見出しだけを抽出して動的に「目次」を表示させることをプラグインなしで実装してみました。
すべてのページに「目次」を表示させたいわけではなく、一部のページに「目次」を表示させたいので、javascriptのコードを該当ページに追加させます。
目次の読みたい箇所をクリックすれば、該当箇所へジャンプする内部リンクも実装。
割と簡単にできましたので、備忘録として残します。
こんな感じ↓で表示できます。h3はわざと入れています。
目次
※記事内で紹介しているHTML・CSS・JavaScript・PHPなどのコードは、作成時点における作成者の最適解です。動作環境やバージョンによって結果が異なる場合があります。コードの使用により生じたいかなる損害やトラブルについても、当サイトは責任を負いかねます。
htmlのコード
カスタムHTMLブロックで以下のコードを入れます。
入れる場所は、目次を表示させたい場所です。
<div id="toc-container">
<div class="mokuji">目次</div>
<ul id="toc"></ul>
</div>
javascriptのコード
カスタムHTMLブロックもしくはテーマのフッターなどに以下のJavaScriptを追加します。
目次には、h2であれば「1.」から番号を付して順番に表示させ、h2の中にh3があれば「1-1.」のような番号を付せるようにしています。
さらに、h2の番号のみに色を付けるように<span>タグで囲みました。色はcssで指定します。
const toc = document.getElementById("toc");
const headings = document.querySelectorAll("h2, h3");
let h2Count = 0;
let h3Count = 0;
headings.forEach((heading, index) => {
const tag = heading.tagName;
let numbering = "";
let numberClass = "";
if (tag === "H2") {
h2Count++;
h3Count = 0;
numbering = `<span class="h2-number">${h2Count}.</span>`;
} else if (tag === "H3") {
h3Count++;
numbering = `${h2Count}-${h3Count}.`;
}
const id = "heading-" + index;
heading.id = id;
const li = document.createElement("li");
li.style.marginLeft = tag === "H3" ? "15px" : "0px";
const a = document.createElement("a");
a.href = "#" + id;
a.innerHTML = numbering + heading.textContent;
li.appendChild(a);
toc.appendChild(li);
});
cssのコード
デザインの調整は、自分好みにしています。デザインセンスはないけど。
子テーマのCSSファイル(style.css)に直接追加しました。
#toc-container {
width: 95%;
max-width: 500px;
background-color: #f9f9f9;
border-left: 5px solid #3968b3;
padding: 20px;
margin: 30px auto;
border-radius: 8px;
font-family: "Helvetica Neue", sans-serif;
box-shadow: 0 2px 5px rgb(57 104 179 / .6);
}
#toc-container .mokuji {
font-size: 18px;
margin-top: 0;
color: #3968b3;
border-bottom: 1px solid #3968b3;
padding-bottom: 0px;
}
#toc {
list-style: none;
padding-left: 0;
margin-top: 10px;
color: #160c28;
font-size: 15px;
}
#toc li {
margin: 5px 0;
}
#toc .h2-number {
color: #3968b3;
font-weight: 500;
}
#toc li a {
text-decoration: none;
color: #333;
transition: color 0.2s ease;
position: relative;
padding-left: 10px;
display: inline-block;
}
#toc li a:hover {
color: #4CAF50;
}