オリジナルテーマ「Compages」使用中

【プラグイン無し】ワードプレスで目次を自動表示させる方法

【プラグイン無し】ワードプレスで目次を自動表示させる方法

ワードプレスには目次を自動表示してくれる便利なプラグイン、「Table Of Contents Plus」や「Easy Table of Contents」どがあります。

インストールしてポチポチっとするだけで目次が表示できるようになるので、非常に便利なんですが……地味に重たくなるのが難点。

最近ではページ速度もSEOに関係していますので、少しでも軽量化するために自作したいって方も少なくないのでは?

そこで【プラグイン無し】ワードプレスで目次を自動表示させる方法を教えようと思います。

jQueryで目次の自動表示機能を作る

まず最初にjQueryで目次を自動表示させるためのコードを書きます。

記述場所は「*.js」の中ならどこでもいいのですが、適当に「indoc.js」でも作ってください。

$(function($) {
  var idcount = 1;
  var indoc = '';
  var currentlevel = 0;
//article内の見出しにindoc-◯のidを付与するための処理
  $("article h2,article h3,article h4", this).each(function() {
    this.id = "indoc-" + idcount;
    idcount++;
    var level = 0;
    if (this.nodeName.toLowerCase() == "h2") {
      level = 1;
    } else if (this.nodeName.toLowerCase() == "h3") {
      level = 2;
    } else if (this.nodeName.toLowerCase() == "h4") {
      level = 3;
    }
//見出しをolとliで囲むための処理
    while (currentlevel < level) {
      indoc += "<ol>";
      currentlevel++;
    }
    while (currentlevel > level) {
      indoc += "</ol>";
      currentlevel--;
    }
    indoc += '<li><a href="#' + this.id + '">' + $(this).html() + "</a></li>\n";
  });
  while (currentlevel > 0) {
    indoc += "</ol>";
    currentlevel--;
  }
//h2の前に目次を表示させるための処理
  if ($("article h2")[0]) {
    $("#indoc").html('<p class="doc-box">目次</p><span class="doc-btn"></span>'+ indoc);
 }
  $('.indoc li').click(function(){
    var href = $(this).find('a').attr('href');
    var target = $(href == '#' || href == '' ? 'html' : href);
    var position = target.offset().top;
    $('html, body').stop().animate({scrollTop:position}, speed, 'easeInOutCirc');
    return false;
  });
});
//目次を開閉させるための処理
$(function () {
  $(".doc-btn").click(function(){
    $("#indoc").toggleClass('active');
    $("#indoc ol").slideToggle(0);
  });
});

こんな感じ。

基本的な部分は プラグインなしで目次を追加!WordPressの目次の作り方! こちらの記事を参考にしていますので、分かりづらい方はそちらを参考にしてください。

function.phpに記述を追加

jQueryが記述できたら、次はfunction.phpに記述を追加していきます。

と言いたいところですが、function.phpにいくつも記述を足していくと見づらくなってしまいます。

なので「lib」というフォルダを作り、その中に「doc-set.php」を作って以下の内容を書き込みます。

<?php
if ( !defined( 'ABSPATH' ) ) exit;

function indoc_in($the_content) {
  if (is_single()) {
    $indoc = "<div id=\"indoc\"></div>";
    $h2 = '/<h2.*?>/i';//H2見出し
    if ( preg_match( $h2, $the_content, $h2s )) {
      $the_content = preg_replace($h2, $indoc.$h2s[0], $the_content, 1);
    }
  }
  return $the_content;
}
add_filter('the_content','indoc_in');
?>

これをfunction.phpで読み込んでやれば、見辛くなることもなく管理もしやすくなります。

読み込むために書くのは、

require_once locate_template('lib/doc-set.php'); // 目次を自動表示

たったのこれだけ。

<footer>の下でjQueryを読み込む

jQueryとfunction.phpの準備ができたら、<footer>の下で先程記述したjQueryの読み込みを行います。

<script>を「async」や「defer」で非同期読み込みしているなら、別に<head>でも構わないです。

書き込む記述は、

<script src="<?php echo get_template_directory_uri(); ?>/js/indoc.js"></script>

でOK。

これでなんのデザインも施されていない目次が、<h2>の前に表示されるようになりました。

cssで見出しにデザインをつける

なんのデザインも施されていないと見た目が悪い+開閉できないので、cssでデザインを施します。

/* ▼indoc */
#indoc {
	position: relative;
	border: 2px solid #efefef;
	border-radius: 4px;
	max-width: 100%;
	margin: 10px auto;
	padding: 10px;
}

#indoc .doc-box {
	margin: 0;
	text-align: center;
	font-weight: 600;
	font-size: 18px;
	display: inline-block;
	border-bottom: 2px solid #333;
	position: relative;
	left: 50%;
	-webkit-transform: translateX(-50%);
	transform: translateX(-50%);
}

#indoc .doc-box::before {
	margin-right: 4px;
	content: '\f15c';
	font-family: 'Font Awesome 5 Free';
	display: inline-block;
	font-weight: 400;
}

#indoc ol {
	display: none;
}

#indoc ol ol {
	margin-left: 1em;
}

#indoc ol ol li {
	font-size: 16px;
	font-weight: normal;
	list-style: decimal;
	border-bottom: 1px dashed #ccc;
	margin-top: 0;
	margin-right: 0;
	list-style-position: inside;
}

#indoc ol ol li::before {
	content: '';
}

#indoc ol li {
	font-size: 16px;
	font-weight: 600;
	margin-top: 16px;
	margin-bottom: 5px;
}

#indoc ol li::before {
	content: '\f0da';
	font-family: 'Font Awesome 5 Free';
	font-weight: 900;
	display: inline-block;
	margni-right: 4px;
}

#indoc ol li a {
	text-decoration: none;
	color: #333;
}

#indoc ol li a:hover {
	color: #999;
}

#indoc .doc-btn::before {
	font-size: 14px;
	position: absolute;
	top: 19px;
	right: 10%;
	content: '[ 表示 ]';
	display: inline-block;
	cursor: pointer;
}

#indoc.active .doc-btn::before {
	position: absolute;
	top: 19px;
	right: calc(10% - 14px);
	content: '[非表示]';
	display: inline-block;
	cursor: pointer;
}
@media screen and (min-width: 768px) {
#indoc ol ol li {
list-style-position: outside;
}
} /* ▲indoc */

これで、今見ているページの目次と同じデザインのものができました。

FontAwesome を使っているので、使用していない方は使えるようにするか、cssを各自で編集してください。