目次
参考:IntersectionObserverを用いる方法
IntersectionObserverを使用して目次をハイライトする方法について説明します。
前述のscrollを使う方法との比較を以下に示します(表1参照)。
| 方法 | メリット | デメリット |
|---|---|---|
| scrollを用いる |
|
|
| IntersectionObserverを用いる |
|
|
実装手順
以下のコードをjavascript.jsに追加します。
jQuery(function ($) {
// サイドバー内にある目次ウィジェットのすべてのリンクを取得
const $tocLinks = $('.sidebar-scroll .widget_toc a');
// 本文中の各見出し要素(<span>)を取得して通常の配列に変換
const headers = $('.entry-content :header span').toArray();
// 要素の状態を監視
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
// 要素が画面内に入った場合
if (entry.isIntersecting) {
const id = entry.target.id;
setActive(id);
}
});
}, {
// 判定基準となる交差領域の余白(画面上部10%を避け、上から10%〜20%のエリアに達した時を発火ポイントとする)
rootMargin: '-10% 0px -80% 0px',
threshold: 0 // 要素が20%見えたタイミングで発火
});
/**
* 指定されたIDに一致する目次リンクに.currentクラスを付与しそれ以外から削除
*
* @param {string} id - 対象の見出しID
* @return {void}
*/
function setActive(id) {
if (!id) return;
$tocLinks.removeClass('current');
$tocLinks.filter(`[href="#${CSS.escape(id)}"]`).addClass('current');
}
// 全見出しに対して監視を開始
headers.forEach(header => observer.observe(header));
});

