ページ内の h1〜h6 見出し を収集してサイドパネルに目次(TOC)を表示するWSIプラグインです。クリックで該当見出しにスムーズスクロール、現在読んでいる位置を自動ハイライトします。長文記事・ドキュメント・仕様書・論文の閲覧に便利。
このサンプルは WSI.addPanel の実用例 を示します。他のサンプルが addButton ベースなのに対し、これはサイドパネルUIの作り方・更新方法・スクロール連動を教材としています。
| API | 役割 |
|---|---|
WSI.addPanel(options) |
画面右側にサイドパネルを表示。title / width / position / content / onClose を指定 |
WSI.addButton(options) |
パネル開閉用のトリガーボタン |
WSI.onPageLoad(callback) |
SPA の URL 変更を検知して TOC を再ビルド |
WSI.getConfig() |
ボタン・パネルの位置・幅を設定可能に |
Element.scrollIntoView({ behavior: 'smooth' }) |
クリック時のスムーズスクロール |
requestAnimationFrame |
スクロール追従のスロットリング(60Hz に抑える) |
outline-panel/
├── plugin.json # ボタン位置・パネル位置・パネル幅を config で指定
├── main.js # TOC生成 / クリックナビ / アクティブ追跡(~100行)
├── style.css # TOC階層スタイルとアクティブ表示
├── README.md
└── outline-panel.zip # WSI にインポートする配布用 ZIP
h1〜h6 のレベルに応じてインデント16px刻みで表示。スタイルも強度を段階化:
| HTML | スタイル |
|---|---|
<h1> |
太字・黒、最左 |
<h2> |
中太、濃いグレー、16px字下げ |
<h3> |
通常、ミドルグレー、32px字下げ |
<h4>〜<h6> |
細字・小サイズ、48〜80px字下げ |
plugin.json の config で表示位置を変更できます。
"config": {
"buttonPosition": "top-left", // ボタン位置: bottom-right/bottom-left/top-right/top-left
"panelPosition": "right", // パネル位置: right / left
"panelWidth": "320px" // パネル幅: 任意のCSS幅(例: "280px", "25vw")
}
ヒント:
buttonPositionとpanelPositionを同じ側(どちらもrightやtop-right系)に置くと、パネルを開いたときに閉じる × ボタンと 📑 ボタンが重なります。デフォルトは「ボタン左・パネル右」で互いに干渉しないようになっています。
[ユーザが 📑 ボタンクリック]
↓
document.querySelectorAll('h1, h2, h3, h4, h5, h6')
↓ 非表示要素を除外、text取得、id自動付与
[WSI.addPanel({ content: 生成HTML })]
↓ ページ右側に <div.wsi-panel> が挿入される
[click listener 付与] → 各 <a> で Element.scrollIntoView
[scroll listener (rAF)] → 見出し位置を測定してアクティブ更新
画面上部 30% (window.innerHeight * 0.3) をトリガーラインとして、このラインより上に位置している最後の見出しをアクティブとする仕組み。
for (let i = 0; i < currentHeadings.length; i++) {
if (currentHeadings[i].element.getBoundingClientRect().top <= triggerY) {
activeIdx = i;
} else break; // 以降は画面下、見なくていい
}
[role="heading"] や Medium のような特殊構造は無視されますscroll-margin-top を CSS で調整するサイトが多い)WSI.fetch のCORS回避デモWSI.storage の永続化デモ