【Javascript】WordPressの記事で目次を自動生成
- 公開日:
- 更新日:
- 文字数:3227文字
はじめに
WordPressの記事に目次をプラグインなしで作成する方法をご紹介。毎回記事に目次をつける作業をしていたら、1,2つの記事なら問題ないですが、それが10,20の記事に目次をつける作業となると、かなり面倒です。
その面倒な目次を自動生成します。
前提・環境
- WordPress OK
- Javascriptの貼り付けができる
HTMLのコード(記事)を書く
<div class="article">
<h2>タイトル</h2>
<p>テキストテキスト</p>
<h3>サブタイトル</h3>
<p>テキストテキスト</p>
<h2>タイトル2</h2>
<p>テキストテキスト</p>
</div>
<div class="mokuji">
<h2>目次</h2>
<div id="mokuji-list"></div>
</div>
mokuji-listというIDにarticle内部のh2,h3の目次を追加します。
Javascriptのコード
// 設定
const TOC_INSERT_SELECTOR = '#mokuji-list'; // [セレクター指定] 目次を挿入する要素 querySelector用
const HEADING_SELECTOR = '.article h2,.article h3'; // [セレクター指定] 収集する見出し要素 querySelectorAll用
const LINK_CLASS_NAME = 'mokuji-a'; // [クラス名] 目次用aタグに追加するクラス名 .無し
const ID_NAME = 'heading'; // [ID名] 目次に追加するID名のプレフィックス #無し
const tocInsertElement = document.querySelector(TOC_INSERT_SELECTOR);
const headingElements = document.querySelectorAll(HEADING_SELECTOR);
const layer = [];
let id = 0;
const uid = () =>`${ID_NAME}${id++}`;
let oldRank = -1;
try {
const createLink = (el) => {
let li = document.createElement('li');
let a = document.createElement('a');
el.id = el.id || uid();
a.href = `#${el.id}`;
a.innerText = el.innerText;
a.className = LINK_CLASS_NAME;
li.appendChild(a);
return li;
};
const findParentElement = (layer, rank, diff) => {
do {
rank += diff;
if (layer[rank]) return layer[rank];
} while (0 < rank && rank < 7);
return false;
};
const appendToc = (el, toc) => {
el.appendChild(toc.cloneNode(true));
};
headingElements.forEach( (el) => {
let rank = Number(el.tagName.substring(1));
let parent = findParentElement(layer, rank, -1);
if (oldRank > rank) layer.length = rank + 1;
if (!layer[rank]) {
layer[rank] = document.createElement('ol');
if (parent.lastChild) parent.lastChild.appendChild(layer[rank]);
}
layer[rank].appendChild(createLink(el));
oldRank = rank;
});
if (layer.length) appendToc(tocInsertElement, findParentElement(layer, 0, 1));
} catch (e) {
//error
}
内部スクロールを導入
内部スクロールを入れたら完了です。あとは、CSSを独自に追加していただければOKです。
$(document).on("click", 'a[href^="#"]', function(){
var speed = 600;
var href= $(this).attr("href");
var target = $(href == "#" || href == "" ? 'html' : href);
var position = target.offset().top - 10;
$('body,html').animate({scrollTop:position}, speed, 'swing');
return false;
});