ワードプレスには目次を自動表示してくれる便利なプラグイン、「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を各自で編集してください。