はじめまして。 昨年からコーダーとしてKNAPに入社しました細田です。 今回は、KNAPのブログで実装した目次の実装方法について紹介したいと思います。 実装方法は様々あると思いますが、プラグインを使わず尚且つ簡単に使えるような実装方法でやっていきます。
1.ショートコード用のPHP関数を自作する
まず、functions.phpにショートコード用の関数を定義します。
function my_mokuji() {
return
'<ol id="mokuji" class="table_of_contents_wrapper">
</ol>';
}
呼び出したいコードだけ書いても、まだショートコードの設定ができていない状態です。
add_shortcode()を使って、ショートコードを定義していきましょう。
add_shortcode('ショートコード名', '使用するfunction名')
の書式で書いていきます。
add_shortcode( 'mokuji', 'my_mokuji' );
2.JavaScriptで動的に見出しを取得して、作ったショートコードに追加していく
最初に記事の内容の見出しにIDを振っていきます。
まず最初に見出し一覧を取得します。 欲しい要素は記事のh2のみで他のh2は除外したいので、今回はl-single_contentの直下のh2のみ取得します。
const lists = document.querySelectorAll('.l-single_content > h2');
次にその要素をfor分を使ってidを振っていきます。
for (let i = 0; i < lists.length; i++) {
lists[i].id += `list${i + 1}`;
}
これで記事内の目的の場所にidが振れました。
次に取得したh2の数だけliタグを作りアンカーとテキストを作成します。 最初に空の変数を作りその中に取得した要素を入れていきます。 先ほど降ったidと同じ値を変数に入れるのと、取得したh2要素のテキストを取得し、それも変数に入れていきます。
const listId = [];
const listTxt = [];
const li = [];
for (let i = 0; i < lists.length; i++) {
listId.push(`list${i + 1}`);
listTxt.push(lists[i].textContent);
}
先ほどのコードと合わせるとこんな感じになります。
const listId = [];
const listTxt = [];
const li = [];
for (let i = 0; i < lists.length; i++) {
lists[i].id += `list${i + 1}`;
listId.push(`list${i + 1}`);
listTxt.push(lists[i].textContent);
}
後は取得した要素を合わせて一つのタグを作っていきます。
for (let i = 0; i < listId.length; i++) {
li.push(`<li><a href="#${listId[i]}">${listTxt[i]}</a></li>`);
}
ショートコードで作ったolタグに挿入します。
const mokuji = document.getElementById('mokuji');
li.forEach(item => {
mokuji.insertAdjacentHTML('beforeend', item);
});
最後に記事によっては目次を入れないこともあるので、条件分岐を付け加えます。
完成したコードは以下です。
const lists = document.querySelectorAll('.l-single_content > h2');
const mokuji = document.getElementById('mokuji');
if( lists.length > 0 ) {
const listId = [];
const listTxt = [];
const li = [];
for (let i = 0; i < lists.length; i++) {
lists[i].id += `list${i + 1}`;
listId.push(`list${i + 1}`);
listTxt.push(lists[i].textContent);
}
for (let i = 0; i < listId.length; i++) {
li.push(`<li><a href="#${listId[i]}">${listTxt[i]}</a></li>`);
}
if(mokuji) {
li.forEach(item => {
mokuji.insertAdjacentHTML('beforeend', item);
});
}
}
後はcssで見た目を整えれば完成です。
記事内にショートコード貼り付ければ簡単に目次が出来るようになりました。
まとめ
今回初めてコードを解説していきましたが、今までやったことなかったのでなかなか難しいですね。 リファクタリングできる余地結構ありそうだな。 自分で記事を書くとなかなか勉強になりますね。 今後も継続していきたいと思います。