Toc.js

ページ内の見出しから目次(Table of Contents)をクライアントサイドのJavaScriptで自動生成するモジュール。

toc_js
3,787 sites
47
drupal.org

インストール

Drupal 11, 10 v3.3.1
composer require 'drupal/toc_js:^3.3'

概要

Toc.jsモジュールは、ページ内の見出し要素(h2, h3など)を検出し、クライアントサイドで自動的に目次(Table of Contents)を生成するJavaScriptライブラリを提供します。サーバーサイドでの処理を必要とせず、軽量で高速な目次生成を実現します。

このモジュールは複数の方法で目次を表示できます。ノードの追加フィールドとして表示する方法、ブロックとして任意のページに配置する方法、そしてテキストフィルターを使用して[toc]ショートコードを目次に変換する方法があります。スムーズスクロール、スクロール時のハイライト、トップへ戻るリンク、スティッキー表示など豊富な機能を備えています。

同一ページに異なる設定の複数の目次を配置することも可能で、アクセシビリティに配慮したARIA属性のサポートや、Ajaxによるページ更新への対応機能も実装されています。

Features

  • クライアントサイドJavaScriptによる高速な目次自動生成
  • ノードの追加フィールドとして目次を表示(コンテンツタイプごとに設定可能)
  • ブロックによる任意ページへの目次配置
  • テキストフィルターによる[toc]ショートコードのサポート
  • スムーズスクロール機能によるスムーズなページ内移動
  • スクロール時の現在位置ハイライト表示
  • 見出しごとの「トップへ戻る」リンクの自動挿入
  • 「目次へ戻る」リンクの挿入(キーボードナビゲーション対応)
  • 目次のスティッキー(固定)表示
  • 折りたたみ可能な階層構造の目次項目(実験的機能)
  • CSSセレクターによる柔軟なコンテナと見出し要素の指定
  • CSS変数によるスクロールオフセットとスティッキーオフセットの設定
  • 不可視の見出しをスキップするオプション
  • 見出しからCSSクラスを継承する機能
  • Ajaxページ更新時の目次自動更新(実験的機能)
  • アクセシビリティに配慮したARIA属性と画面リーダー対応

Use Cases

長いドキュメントページの目次

ヘルプドキュメントやFAQなど、長いコンテンツを持つページに自動で目次を生成します。コンテンツタイプの設定で「Enable Table of contents」を有効にし、「表示管理」でTocフィールドをコンテンツの上部に配置します。見出しh2とh3を対象にし、スムーズスクロールとスクロール時ハイライトを有効にすることで、ユーザーが目的のセクションに素早くアクセスできます。

サイドバーに固定表示する目次

ブログ記事やチュートリアルページのサイドバーに、スクロールしても追従する目次を表示します。Toc.jsブロックをサイドバーリージョンに配置し、「Sticky」オプションを有効化します。「Sticky offset」でヘッダーの高さを考慮したオフセットを設定し、「Highlight on scroll」で現在読んでいるセクションをハイライト表示します。

ナレッジベースの記事ごとに目次の有無を制御

ナレッジベースサイトで、短い記事には目次を表示せず、長い記事にのみ目次を表示します。toc_js_per_nodeサブモジュールを有効化し、コンテンツタイプで「Permit to enable/disable toc per node」をオンにします。「Default state」を「Enabled」に設定しておき、短い記事の編集時に「Display a table of contents」チェックを外します。また、「Minimum elements」設定で見出しが一定数以上ある場合のみ表示することも可能です。

エディタが記事内に目次を挿入

CKEditorやその他のリッチテキストエディタで、記事の任意の位置に目次を挿入できるようにします。toc_js_filterサブモジュールを有効化し、該当するテキストフォーマットの設定で「TOC.js shortcode: [toc]」フィルターを有効にします。エディタは記事本文に[toc]と入力するだけで、その位置に目次が自動生成されます。

複数言語サイトでの目次ラベルのカスタマイズ

多言語サイトで目次のタイトルや「トップへ戻る」リンクのラベルを各言語に合わせて設定します。コンテンツタイプの設定で「Title」に日本語で「目次」と入力し、「Back to top link label」に「ページトップへ」と設定します。翻訳可能なラベルフィールドにより、各言語版で適切なラベルが表示されます。

アクセシビリティ対応の目次ナビゲーション

スクリーンリーダーユーザーやキーボードナビゲーションユーザーに配慮した目次を実装します。「Heading focus」を有効にして目次リンククリック時に見出しにフォーカスを設定し、「Show back to toc links」を有効にして見出しから目次への戻りリンクを提供します。「Back to toc link CSS classes」に「visually-hidden-focusable」を設定することで、通常は非表示ですがフォーカス時に表示されるリンクになります。

Ajaxで動的に更新されるコンテンツの目次

Views Infinite ScrollやLoad Moreなど、Ajaxでコンテンツが動的に追加されるページの目次を自動更新します。「Ajax page updates handling」オプションを有効にし、必要に応じて「Custom observable container selector」でAjax更新を監視するコンテナを指定します。MutationObserverにより、コンテンツの追加・削除時に目次が自動的に再生成されます。

Tips

  • CSSカスタム変数を活用: scroll-to-offsetやsticky-offsetでvar()構文を使用すると、テーマのCSS変数と連携した柔軟な設定が可能です。
  • テンプレートのカスタマイズ: toc-js.html.twigをテーマにコピーし、toc-js--node--article.html.twigのような名前で保存すると、コンテンツタイプごとに異なるマークアップを適用できます。
  • パフォーマンス最適化: 大量の見出しがあるページでは「Skip invisible headings」を有効にし、不要な見出しを除外することでパフォーマンスを向上できます。
  • 見出しのクリーンアップ: 見出しにアイコンや装飾的な要素が含まれる場合、「Heading cleanup selector」に該当するセレクター(例: .icon, .decoration)を指定して目次から除外できます。
  • アクセシビリティ: 「Back to toc links」を有効にし、CSSクラスに「visually-hidden-focusable」を設定すると、キーボードユーザーにとって便利なナビゲーションを提供しつつ、視覚的には目立たないリンクを実装できます。
  • Ajaxコンテンツ: Views Infinite Scrollなどと組み合わせる場合は「Ajax page updates handling」を有効にし、適切なobservable_selectorを設定してください。
  • 最小要素数の活用: 「Minimum elements」を2や3に設定すると、見出しが少ない短い記事では目次が表示されず、長い記事のみに表示されるようになります。

Technical Details

Admin Pages 3
コンテンツタイプ編集画面 - Table of contents設定 /admin/structure/types/manage/{node_type}

各コンテンツタイプに対してToc.jsの目次機能を有効化し、詳細な設定を行います。設定はコンテンツタイプの編集画面内の「Table of contents」セクションで行います。

表示管理 /admin/structure/types/manage/{node_type}/display

コンテンツタイプの表示管理画面で、Toc(目次)追加フィールドの表示位置を設定します。目次機能を有効にした後、この画面で「Toc」フィールドを目的の位置にドラッグします。

ブロックレイアウト /admin/structure/block

Toc.jsブロックを任意のリージョンに配置します。「ブロックを配置」から「Toc js」カテゴリ内の「Toc.js block」を選択して設定します。

権限 2
Administer Toc.js

コンテンツタイプごとのToc.js目次設定を管理できます。このパーミッションまたは「ノードを管理」パーミッションが必要です。

Administer Toc.js per node

ノード単位でToc.jsの目次表示の有効/無効を切り替えられます。このパーミッションまたは「ノードを管理」パーミッションが必要です。(toc_js_per_nodeサブモジュール)

Hooks 5
hook_theme

toc_jsテーマフックを定義。目次のHTMLレンダリングをカスタマイズ可能にします。

hook_theme_suggestions_toc_js_alter

エンティティタイプ、バンドル、エンティティIDに基づいたテーマサジェスチョンを追加。より詳細なテンプレートオーバーライドが可能。

hook_entity_extra_field_info

Toc.jsが有効なコンテンツタイプに「Toc」追加フィールドを登録

hook_node_view

ノード表示時に目次をレンダー配列に追加

hook_form_node_type_form_alter

コンテンツタイプ編集フォームにToc.js設定セクションを追加

Troubleshooting 6
目次が表示されない

1) コンテンツタイプの「Table of contents」で「Enable Table of contents」がチェックされているか確認。2) 「表示管理」でTocフィールドが有効なリージョンに配置されているか確認(「無効」エリアにないこと)。3) 「Selectors」設定が実際のコンテンツの見出しタグと一致しているか確認。4) 「Container」設定が正しいセレクターか確認(デフォルトは.node)。5) 「Minimum elements」が実際の見出し数以下か確認。

スティッキー表示が正しく機能しない

1) 「Sticky offset」に適切な値が設定されているか確認(固定ヘッダーがある場合はその高さを指定)。2) CSS変数構文を使用している場合、その変数がテーマで定義されているか確認。3) 目次の親要素に position: relative や overflow: hidden が設定されていないか確認。4) 「Toc container selector」で適切な親要素を指定しているか確認。

スムーズスクロールで見出しが隠れる

「Scroll offset」に固定ヘッダーやツールバーの高さを考慮した値を設定します。例: 「100px」や「var(--header-height, 80px)」。また、見出しにscroll-margin-topを適用するCSSをテーマに追加することも有効です。

目次のリンクがアンカーにジャンプしない

1) ページ内に同じIDを持つ要素が存在しないか確認。2) JavaScriptエラーがブラウザコンソールに出ていないか確認。3) jQueryとonceライブラリが正しく読み込まれているか確認。

ノード単位の目次制御が表示されない

1) toc_js_per_nodeサブモジュールが有効化されているか確認。2) コンテンツタイプの設定で「Permit to enable/disable toc per node」がチェックされているか確認。3) 「Administer Toc.js per node」または「Administer nodes」パーミッションがあるか確認。

[toc]ショートコードが目次に変換されない

1) toc_js_filterサブモジュールが有効化されているか確認。2) 使用しているテキストフォーマットで「TOC.js shortcode: [toc]」フィルターが有効か確認。3) フィルターの処理順序が適切か確認(HTMLを生成するフィルターの後に配置)。

Security Notes 3
  • Toc.jsの設定フィールドではXSSフィルタリングが適用されています。特にタイトルやラベルフィールドではXss::filter()を使用し、許可されたHTMLタグ(spanのみ)以外は除去されます。
  • CSSセレクターやクラス名の入力値はHtml::cleanCssIdentifier()で処理され、不正な文字が除去されます。
  • ユーザー入力値がdata-*属性として出力される際にもXSSフィルタリングが適用されています。