WordPressでプラグインを使わずに目次を表示させる

WordPressの投稿ページで、H2やH3見出しだけを抽出して動的に「目次」を表示させることをプラグインなしで実装してみました。

すべてのページに「目次」を表示させたいわけではなく、一部のページに「目次」を表示させたいので、javascriptのコードを該当ページに追加させます。

目次の読みたい箇所をクリックすれば、該当箇所へジャンプする内部リンクも実装。

割と簡単にできましたので、備忘録として残します。

こんな感じ↓で表示できます。h3はわざと入れています。

目次
    スポンサーリンク

    htmlのコード

    カスタムHTMLブロックで以下のコードを入れます。

    入れる場所は、目次を表示させたい場所です。

    <div id="toc-container">
      <div class="mokuji">目次</div>
      <ul id="toc"></ul>
    </div>

    javascriptのコード

    カスタムHTMLブロックもしくはテーマのフッターなどに以下のJavaScriptを追加します。

    目次には、h2であれば「1.」から番号を付して順番に表示させ、h2の中にh3があれば「1-1.」のような番号を付せるようにしています。

    さらに、h2の番号のみに色を付けるように<span>タグで囲みました。色はcssで指定します。

    const toc = document.getElementById("toc");
    const headings = document.querySelectorAll("h2, h3");
    let h2Count = 0;
    let h3Count = 0;
    
    headings.forEach((heading, index) => {
      const tag = heading.tagName;
      let numbering = "";
      let numberClass = "";
    
      if (tag === "H2") {
        h2Count++;
        h3Count = 0;
        numbering = `<span class="h2-number">${h2Count}.</span>`;
      } else if (tag === "H3") {
        h3Count++;
        numbering = `${h2Count}-${h3Count}.`;
      }
    
      const id = "heading-" + index;
      heading.id = id;
      const li = document.createElement("li");
      li.style.marginLeft = tag === "H3" ? "15px" : "0px";
      const a = document.createElement("a");
      a.href = "#" + id;
      a.innerHTML = numbering + heading.textContent;
      li.appendChild(a);
      toc.appendChild(li);
    });
    スポンサーリンク

    cssのコード

    デザインの調整は、自分好みにしています。デザインセンスはないけど。

    子テーマのCSSファイル(style.css)に直接追加しました。

    #toc-container {
      width: 95%;
      max-width: 500px;
      background-color: #f9f9f9;
      border-left: 5px solid #3968b3;
      padding: 20px;
      margin: 30px auto;
      border-radius: 8px;
      font-family: "Helvetica Neue", sans-serif;
      box-shadow: 0 2px 5px rgb(57 104 179 / .6);
    }
    #toc-container .mokuji {
      font-size: 18px;
      margin-top: 0;
      color: #3968b3;
      border-bottom: 1px solid #3968b3;
      padding-bottom: 0px;
    }
    #toc {
      list-style: none;
      padding-left: 0;
      margin-top: 10px;
      color: #160c28;
      font-size: 15px;
    }
    #toc li {
      margin: 5px 0;
    }
    #toc .h2-number {
      color: #3968b3;
      font-weight: 500;
    }
    #toc li a {
      text-decoration: none;
      color: #333;
      transition: color 0.2s ease;
      position: relative;
      padding-left: 10px;
      display: inline-block;
    }
    #toc li a:hover {
      color: #4CAF50;
    }

    デモ:h3はこんな感じです

    デモ:cssはお好みで調整してね

    デモ:javascriptにもスタイルの一部があるよ