楽天セール開催中!ポイント最大11倍! セール会場へ

SWELL│「目次へ戻る」のアンカーリンクを自動挿入するカスタマイズ

swell-back-toc

SWELLの記事で、2つ目以降のH2見出しの直前に「目次に戻る」リンクを追加する方法です。実際に本文内の目次がある場合だけ追加し、ブログパーツやモーダル内の見出しを対象から外します。この記事自体でも同じJavaScriptが動いています。

目次

著者

WEB制作をしているデジタルノマド
WordPressのカスタマイズが好きで、色々と自作しています。

WordPressのカスタマイズに困ったらご相談ください!

動く見本と適用範囲

次の見出しから表示される「目次に戻る」をクリック、またはTabで選んでEnterを押すと、本文の目次へ戻ります。記事を読み直すための補助リンクです。最初のH2、目次のない記事、H2が1つだけの記事には追加しません。

以下のPHPは通常の投稿ページだけが対象です。カテゴリーアーカイブ、固定ページ、カスタム投稿タイプには適用しません。SWELLの本文と目次のHTML構造を前提にしているため、他テーマ共通のコードではありません。

PHPを子テーマまたはスニペットに追加する

変更前をバックアップし、子テーマのfunctions.phpのPHP内、またはCode SnippetsのPHPスニペットのどちらか一方へ追加します。PHP開始タグは既存のタグ内に重ねません。親テーマや記事のカスタムHTMLブロックへPHPを貼らないでください。

add_action('wp_footer', function () {
    if (!is_singular('post')) return;
    ?>
    <script>
(() => {
  const init = () => {
    const body = document.querySelector('#main_content article .post_content');
    if (!body || body.dataset.wazaBackReady) return;
    const toc = body.querySelector('.p-toc:not(.-modal)');
    if (!toc || toc.closest('.post_content') !== body) return;
    const headings = [...body.querySelectorAll('h2')].filter(h =>
      h.closest('.post_content') === body && !h.closest('.p-toc, .p-blogParts, dialog, details')
    );
    if (headings.length < 2) return;
    const id = toc.id || 'waza-main-toc';
    const occupied = document.getElementById(id);
    if (occupied) { if (occupied !== toc) return; }
    toc.id = id;
    if (!toc.hasAttribute('tabindex')) toc.tabIndex = -1;
    body.dataset.wazaBackReady = '1';
    headings.slice(1).forEach(heading => {
      const wrapper = document.createElement('p');
      wrapper.className = 'waza-back-toc';
      const link = document.createElement('a');
      link.href = '#' + id;
      link.textContent = '目次に戻る';
      link.addEventListener('click', () => toc.focus({ preventScroll: true }));
      wrapper.append(link);
      heading.before(wrapper);
    });
  };
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init, { once: true });
  } else {
    init();
  }
})();
    </script>
    <?php
});

旧版のmotoki_back_tocとmotoki_add_toc_idは先に停止します。旧版のHTML置換と今回のJavaScriptを同時に動かすと、リンクが重複する原因になります。

余白と固定ヘッダーの重なりを調整する

次のCSSを追加CSSか子テーマのstyle.cssへ貼ります。120pxは移動先の上側に確保する余白です。固定ヘッダーの高さに合わせて変更してください。既存の目次に独自IDが付いている場合は、先頭のセレクターをそのIDに合わせます。

#waza-main-toc { scroll-margin-top: 120px; }
.waza-back-toc { margin: 2em 0 .5em; text-align: right; }
.waza-back-toc a:focus-visible { outline: 3px solid #1769aa; outline-offset: 3px; }

仕組み:本文の目次を見つけてからリンクを作る

PHPで本文の文字列に一律でリンクを差し込むのではなく、ページ内の目次と見出しを確認してから作成します。リンク先は本文内の目次です。画面下部などにあるモーダル用の目次は使いません。既存の目次IDは維持し、IDがない場合だけwaza-main-tocを付けます。

リンクのクリック時には目次へフォーカスも移します。JavaScriptが使えない場合は追加リンクが出ませんが、元の記事と目次はそのまま読めます。動的に後から追加される見出しを監視するコードではありません。

確認方法と元に戻す方法

保存後にキャッシュを消し、公開ページで2つ目以降のH2にだけリンクが付くか確認します。目次がない記事には追加されないこと、リンクをEnterで実行して本文の目次へ戻れること、固定ヘッダーに隠れないことをPCとスマホ幅で確認してください。

戻す場合は追加したPHPスニペットを無効化するか、そのPHPとCSSを取り除きます。記事本文を書き換える処理ではないため、各記事からリンクを削除して回る必要はありません。SWELLのHTML構造や遅延実行設定が変わった場合は再確認してください。

旧GitHub例とは同期していないため、この本文のコードを使用してください。

キーボードで本文の目次へ戻る

見出しの前にある「目次へ戻る」をTabで選び、Enterを押します。移動先は本文の目次#waza-main-tocで、目次自体へフォーカスが移ります。最初のH2の前にはリンクを作らず、2つ目以降のH2を対象にします。戻った位置で目次リンクを選び直して、別の見出しへ移動できます。

目次の文言を短くする場合は指定文字列の省略、サイドバーで現在位置を示す場合はハイライトの方法を参照してください。

公開画面での確認

スマホ幅390pxで「目次へ戻る」をEnterで選び、本文の目次へフォーカスが移った状態です。

スマホで目次へ戻り本文の目次にフォーカスした画面
2026年10月2日、WAZAの公開ページで撮影。
  • URLをコピーしました!

実装を任せたい方へ

SWELLのカスタマイズ代行

記事のコードをそのまま使うのが不安な場合や、サイトに合わせた調整が必要な場合は当社が実装します。1時間 ¥8,000〜(税込)。テーマ更新に強い書き方で納品します。

WAZAの有料記事のサブスクリプションも開始しました。

サービス

Service

WordPressサイトのカスタマイズのサービスに関心がありましたら、ぜひ詳細をご覧ください。

目次