
WordPressでは記事の冒頭に目次を入れることが多いですが、サイドバーに表示している人もいますよね。
目次があれば全体の流れがつかめて便利ですし、
サイドバーでは「今どこを読んでいるか」がハイライトされたりすると更に親切。特に長い記事では読む側も現在地が分かってとても助かります。
ということで、今回はスクロールに連動して
今どのあたりを読んでるのかが分かる用、目次項目を自動ハイライトする方法をご紹介。
Cocoonを例にコピペOKのコード付きで解説しますが、
目次の構造はどのテーマでも大体同じだと思いますので、Cocoon以外でも一度お試しになってみてください。
目次とハイライト表示
念のため、まずどのように目次を表示しているか、
前提をあわせておきましょう。
今回は以下のHTML構造となっている目次にあわせてのカスタマイズになります。
なんのこっちゃ分からない!という場合では、
Cocoonを使っていれば気にしないでOKです。
Cocoon以外のテーマでも(多分ですが)この構造になってると思いますので、まず動作するか試してみる、というのも良いと思います。
1 2 3 4 5 6 7 8 9 | <div class="toc"> <!-- このクラス名が異なれば、JavaScriptをそれに合わせるよう修正 --> <div class="xxxxxxx"> <!-- クラス名は自由、なくてもOK --> <ol class="xxxxxxx"> <!-- olでもulでもOK、クラス名も自由 --> <li><a href="#aaa">見出し1</a></li> <li><a href="#bbb">見出し2</a></li> <li><a href="#ccc">見出し3</a></li> </ol> </div> </div> |
では以降、Cocoonの例ですが、
目次をどうやってサイドバーに貼り付けているかも念のため見ておくと、Cocoonでは「目次のウイジェットをペタっと貼るだけ」。

※)Cocoonでは、「サイドバースクロール追従」(スクロールしても上に消えずに表示しようと付いて来るエリア)があり、そこに目次のウイジェット(図の中の [C] 目次)を貼るだけ。
こうして貼った目次は、以下のようにサイドバーに表示され、
下の方にスクロールしても追従して、いつも見れように表示されます。

スクロールしても、いつでも目次が見れるというのは良いですが、今どこを読んでるかが分かると、更に全体の中の位置が分かって分かりやすいですよね。
そこで、JavaScript、CSSを使って
「今画面に表示されている箇所の目次の項目」をハイライトする、っていうことをしてみます。
実際には、以下のようにな表示になります。

コードを貼り付けて実現する
この「スクロールすると目次内の項目がハイライトする」は凄く簡単で、以下2つを行えばOK。
- 1)JavaScriptのコードを貼り付ける
- 2)CSSのコードを貼り付ける
コピペでOKですので、是非試してみてください。
(Cocoonならそのまま動作するはず)
また、JavaScriptやCSSの貼り付け方が分からない場合、
以下で紹介しているプラグインを使ってみるのがおすすめ。
【WordPress】CSSやJavaScript,jQueryを簡単追加する方法!プラグインのおすすめ
このプラグインを使えば、凄く簡単に貼り付けが出来ます。
1)JavaScriptのコードを貼り付ける
まずは以下のJapaScriptのコードを、プラグインなどを活用して、
ブログ内に貼り付けましょう。
(以下コードには何をしているのかコメントも入れてるので、ちょっと長くなってます)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | <script> document.addEventListener("DOMContentLoaded", function () { // 目次内のすべてのリンクを取得 const tocLinks = document.querySelectorAll('.toc a'); // ← ★この行が該当! // 各リンクのhref(#toc1 など)からIDを抽出 const headingIDs = Array.from(tocLinks).map(link => link.getAttribute('href').substring(1)); // 対応する本文中の見出し要素(id="toc1" など)を取得 const headings = headingIDs.map(id => document.getElementById(id)).filter(el => el); // IntersectionObserver(表示エリア内に入ったかを監視するAPI)を作成 const observer = new IntersectionObserver(entries => { entries.forEach(entry => { if (entry.isIntersecting) { // 表示された見出しのIDを取得 const id = entry.target.getAttribute('id'); // すべての目次リンクに対して処理を行う tocLinks.forEach(link => { const li = link.closest('li'); // リンクの親の<li>要素を取得 if (!li) return; // 現在表示中の見出しIDと一致するリンクなら<li>に.activeを付ける if (link.getAttribute('href') === '#' + id) { li.classList.add('active'); } else { li.classList.remove('active'); // 一致しないものは外す } }); } }); }, { rootMargin: '0px 0px -70% 0px', // 画面の上部から70%の位置を境に判定 threshold: 0.1 // 10%以上見えていれば「表示中」と判定 }); // 各見出し要素を監視対象に追加 headings.forEach(h => observer.observe(h)); }); </script> |
※)4行目について:
上の方で見た「このクラス名が異なれば、JavaScriptをそれに合わせるよう修正」はこの行の「toc」を置き換える
このコードは以下のようなことをしてますが、
あぁ、そんなことをしてるのね、ぐらいの参考までに。
- 1)まず目次内にあるリンクをすべて集める
- 2)そのリンクに対する記事内の見出し(H2やH3など)を見つけておく
- 3)現在、どこの見出しが表示されたかを見張り、「この見出しが出た!」とわかると、該当する見出し項目に印をつける(<li>に”active”をつける)
最後の3にある「active」が付くと、
次で紹介するCSSで設定された色に変わる、ってわけです。
2)CSSのコードを貼り付ける
では同様にプラグインなどを使って、以下のCSSを貼り付けましょう。
1 2 3 4 5 | #sidebar .toc-list li.active { background-color: #ffe6e6; /* 背景色 */ border-left: 4px solid #d00; /* 左の線 */ padding-left: 6px; /* 左の内側余白 */ } |
必要に応じて、背景色を変えたり、
「太字(font-weight:bold;)」を追加するなどすると
そのブログのデザインにあったカスタマイズが出来ると思います。
このサイトではここから若干変更していて、
先頭の数字含めてハイライトするようにしています。
Cocoonだけの対応になると思いますが、
それをちょっとご紹介
先頭の数字も含めてハイライト
まずCocoonの目次の設定で、
「目次ナンバーの表示」を「数字詳細(ex 1.1.1)」を選択。

この設定をすると、目次中の小見出しが、
「1.1」, 「1.2」みたいに少し詳しくナンバリングされて表示されるようになります。
詳しくは割愛しますが、これにより目次内のHTMLが若干代わり、
ハイライトが先頭の数字を含むように変わるんですね。

ただ、数字を含めた分、右側にずれますので、
CSSは以下に差し替えてみてください。
1 2 3 4 5 6 | #sidebar .toc-list li.active { background-color: #ffe6e6; border-left: 4px solid #d00; padding-left: 6px; margin-left:-10px; /* 左端の線と余白分を打ち消す */ } |
5行目を追加しただけですが、
ここを追加しないと、ハイライト行が10px右にづれて、
少しガタツキのある表示になります。
気にしない場合には特に追加不要ですが、
ブログのデザインにあうように調整して見てくださいね。
※)実際の動作例は、このブログのサイドバーにある目次を見てみてください。
では良いブログを作って行きましょう!
ブログの収益化に興味があったら、
以下にも是非登録してみてください。
(いいことあると思いますよ!)
コメント