JavaScriptでWordPressの記事ページに目次を生成しよう【プラグインいらず】

目次

JavaScriptでWordPressの記事ページに目次を表示する

今回は自作テーマの記事ページに目次を生成する方法を紹介します。
JavaScriptで作成します。

「プラグインでもいいやん」
って思われるかたもいらっしゃるでしょうし、私もそう思います。

しかし私もコーダーの端くれ。
自分で作れそうなものは自分で作りたい!
と思い立ち、頑張ってみました。
プログラムの練習にもなりますしね!

作成結果の見た目は私の記事ページの目次と同じになります。

コピペでもつかえるので、ぜひ参考にしてみてください!

【Point】JavaScriptでWordPressの記事ページに目次を生成しよう

  • 記事内のh2タグすべてにクラスを付与する
  • h2タグをすべて取得する
  • 取得したh2タグのテキストを抜き出す
  • 目次用のHTMLを生成して、それに抽出したテキストを設定し、アンカーリンクを設定する
  • 目次の対象要素に完成したHTMLを順に挿入する

【基本コード】JavaScriptでWordPressの記事ページに目次を生成しよう

JavaScript

//変数の設定
var articleTitles = document.querySelectorAll('.article-content h2'); //記事内のh2タグをすべて取得
var indexArea = document.querySelector('.index-area'); //目次のエリアを取得
var indexList = document.querySelector('.index-list'); //目次の親要素を取得
var indexTitles = []; //生成した目次を保存する配列

//h2があれば処理を実行
if(articleTitles.length){
  
  //h2があれば、目次のエリアを表示
  indexArea.classList.add('show');
  
  //取得したh2にidを設定し、目次のHTMLにアンカーリンクと抽出したテキストを設定する
  articleTitles.forEach(function(title, index) {
    var id = 'articleTitle-' + index;
    title.setAttribute('id', id);
    
    var text = title.textContent;
    var indexHtml = '<li class="index"><a class="scroll" href="#' + id + '">' + text + '</a></li>';
    indexTitles.push(indexHtml);
  });
}

//対象要素に目次を順に挿入
indexTitles.forEach(function(title) {
  indexList.insertAdjacentHTML('beforeend', title);
});

HTML

<div class="index-area">
    <h2>目次</h2>
    <ul class="index-list">
    </ul>
</div>

SCSS

.index-area{
  display: none;
  padding: 1.5em;
  background: #f8f9fa;
  margin-bottom: 2em;
  
  h2{
    margin-bottom: 1em;
  }
  
  .index-list{
    list-style: initial;
    margin-left: 1.3em;
    
    li{
      + li{
        margin-top: 1em;
      }
      
      a{
        color: #17a2b8;
        text-decoration: underline;
      }
    }
  }
  
  &.show{
    display: block;
  }
}

【解説】JavaScriptでWordPressの記事ページに目次を生成しよう

HTMLは目次を表示したい場所にそのままコピペしてください。
クラス名は変更していただいても構いませんが、その際はJavaScriptファイルも修正してください。

見た目を変えたい場合はCSSも適宜修正してください。

必要な要素を変数に設定する

今回のプログラムで必要な要素を変数として用意します。
それぞれの説明は下記のとおりです。

var articleTitles = document.querySelectorAll('.article-content h2'); //記事内のh2タグをすべて取得
var indexArea = document.querySelector('.index-area'); //目次のエリアを取得
var indexList = document.querySelector('.index-list'); //目次の親要素を取得
var indexTitles = []; //生成した目次を保存する配列

h2タグがあれば、目次エリアを表示する

目次エリアはh2タグがなければ表示する必要がありませんので、
最初はCSSで非表示にしています。

h2タグがひとつでもあれば、目次の要素に.showクラスを付与して、表示する仕様にしました。

//h2があれば処理を実行
if(articleTitles.length){
  
  //h2があれば、目次のエリアを表示
  indexArea.classList.add('show');

}

取得したh2タグにidを設定し、アンカーリンクの下準備をする

WordPressの記事作成画面でh2タグを使用しただけでは、id属性は自動で設定されません。
アンカーリンクを使用するにはid属性を設定する必要があるので、その処理を作成します。

//h2があれば処理を実行
if(articleTitles.length){
  
  //h2があれば、目次のエリアを表示
  indexArea.classList.add('show');
  
  //取得したh2にidを設定し、目次のHTMLにアンカーリンクと抽出したテキストを設定する
  articleTitles.forEach(function(title, index) {
    var id = 'articleTitle-' + index;
    title.setAttribute('id', id);
  });

}

forEachメソッドは順番に配列の要素にアクセスするためのメソッドです。
この機能を利用して、取得したh2が格納されている配列(articleTitles)の要素に順番にアクセスします。

またforEachメソッドの引数にはそれぞれ下記の値が自動的に入ります。

  • 第1引数:アクセスした要素
  • 第2引数:順番

h2タグにid属性を設定するために、第2引数の「順番」(index)を利用して加工します。

var id = 'articleTitle-' + index; //h2タグに設定するidの値を作成(articleTitle-0、articleTitle-1 ...)
title.setAttribute('id', id); //id="articleTitle-0"、id="articleTitle-1" ...

setAttibuteメソッドは属性に値を設定します。
この機能を利用して、作成した値(articleTitle-●●)をid属性に設定します。

これでアンカーリンクの下準備は完了です!

ちなみに、
配列と説明していますが厳密には配列ではありません
querySelectorAllメソッドの戻り値はNodeListという配列のようなものです。
このあたりの説明はまたの機会に!

目次用のHTMLを生成する

次に目次用のHTMLを生成します。

目次には以下の情報が必要です。

  1. アンカーリンク
  2. h2のテキスト

アンカーリンクは前項で作成したので、ここではh2のテキストのみを抽出します。
そのあと「アンカーリンク」と「抽出したテキスト」をHTMLタグに設定し、
完成した目次用のHTMLを配列に保存していきます。

//h2があれば処理を実行
if(articleTitles.length){
  
  //h2があれば、目次のエリアを表示
  indexArea.classList.add('show');
  
  //取得したh2にidを設定し、目次のHTMLにアンカーリンクと抽出したテキストを設定する
  articleTitles.forEach(function(title, index) {
    var id = 'articleTitle-' + index;
    title.setAttribute('id', id);
    
    var text = title.textContent;
    var indexHtml = '<li class="index"><a class="scroll" href="#' + id + '">' + text + '</a></li>';
    indexTitles.push(indexHtml);
  });
}

textContentプロパティには要素の文字列情報が保存されています。
このプロパティにアクセスして、タイトルのテキストを取得します。

var text = title.textContent;

ここまでで「アンカーリンク」と「タイトルのテキスト」が準備できたので、
それらをHTMLに設定し、完成形のHTMLを配列(indexTitles)に保存していきます。

var indexHtml = '<li class="index"><a class="scroll" href="#' + id + '">' + text + '</a></li>';
indexTitles.push(indexHtml);

pushは配列の最後に要素を追加するメソッドです。
こちらを使用して配列(indexTitles)に要素(indexHtml)を順番に追加してきます。

これで必要な要素が準備できました。
あとは目次のエリアにこれらを挿入するだけです!

目次の対象要素に作成したHTMLを順に挿入する

要素を挿入するメソッドとしてinsertAdjacentHTMLを使用します。

//対象要素に目次を順に挿入
indexTitles.forEach(function(title) {
  indexList.insertAdjacentHTML('beforeend', title);
});

insertAdjacentHTMLメソッドは対象要素を基準として、
第1引数で指定した場所」に「第2引数で指定した要素」を挿入します。

今回の例でいうと以下のような処理が実行されます。

  • indexList(目次が挿入される要素)の
  • beforeend(閉じタグの前)に
  • title(目次用のHTML)を挿入

以上です。
これで目次のリストが完成です!

【まとめ】JavaScriptでWordPressの記事ページに目次を生成しよう

お疲れさまでした!

今回のようにおさえるポイントが多い場合でも、
必要な要素や手順を事前に洗い出しておくことで、混乱することなくプログラムを作成することができます。

焦ったときは「急がば回れ」の原点に立ち返りましょう!

以上です。
少しでもお役に立てたら嬉しいです。

Share

Comments

  1. みと より:

    参考になりました!ありがとうございます!(*´꒳`*)

コメントを残す

入力エリアすべてが必須項目です。メールアドレスが公開されることはありません。

内容をご確認の上、送信してください。

CAPTCHA