www.ni4.jp

ブログ記事の目次をJavaScriptで自動生成してみた

ども、どもども。

先日、ブログデザインをリニューアルしたときから記事の中に目次をつけたいと思っていたので、この週末にやってみました。

当初、JavaScriptでゼロからチャレンジしてみようと思っていたのですが、調べてみるとjQueryのプラグインなどもすでにあったので、今回はそちらを利用することに。

今回使用したのはこちら。
なんと、2014年の記事!(小粋空間さん、いつもお世話になっております)

ブログ記事の目次については賛否両論ありますが、ワタシもここ最近になってnoteを読むことが増えたり技術系のブログを読んでいるときに「目次って便利だな」と思うようになった感じです。

利用方法は配布元サイトにも書いてありますが、今回設置した手順をまとめておこうと思います。

Table of Contents

ちなみに、この上に表示されている目次がこのブログ記事で自動生成したものです!

jQuery.toc.jsプラグインを設置する

まずはこの作業の中心となる jQuery.toc.js を上記配布元からダウンロードしてきます。
記事中のリンクを開くとテキストファイルが表示されるので、それをコピーしてローカルに保存そればOK

あとは記事にあるとおり、jQuery.toc.js のインストールと読み込み、表示する部分にコード(id属性値つきの任意の要素)を設置、必要に応じてオプションを調整して完了です。
私はオプションを以下のようにしています。

$(function(){
    $(".entry-more").toc({
        startLevel: 'h2',
        listType: 'ul',
        target: 'headline'
    });
});

上記の .entry-more の部分、上記記事では body になっていますが、これだとHTMLに含まれるすべてのhタグが目次になってしまうので、目次を作るブロックにあわせて変更する必要があります。

CSSを調整する

実際に出力されるコードはこちら

<div id="headline">
  <ul>
    <li><a href="#chapter1">jQuery.toc.jsプラグインを設置する</a></li>
    <li><a href="#chapter2">CSSを調整する</a></li>
    <li><a href="#chapter3">目次に見出しをつける</a></li>
    <li><a href="#chapter4">記事毎に目次を入れるかどうかを決める</a></li>
    <li><a href="#chapter5">スムーススクロールを入れる</a></li>
  </ul>
</div>

このHTMLに合わせてCSSで装飾を施します。

目次に見出しをつける

このままでもOKなのですが、それが目次であるとはっきりわかったほうが良いと思ったので、今回は見出しもつけました。
以下の部分がそれです。

<div class="h-title">Table of Contents</div>

こちらにもCSSで装飾を入れ、完成したのが上記の目次になります。
これで目次を入れるところまでは完成。

こちらの記事でも目次を確認することができます。

記事毎に目次を入れるかどうかを決める

これで完成でも良かったのですが、私が書くブログ記事は必ずしも目次が必要ではありません。
例えばこんな記事では目次は必要ないのです(笑)

このブログはMovableType.netを使用しているので、必要な記事にだけ目次を追加できるようにカスタムフィールドで以下のようなスイッチを作りました。

テンプレートのコードはこんな感じです。

<mt:If tag="CustomFieldValue" identifier="TableOfContents">
  <div class="h-title">Table of Contents</div>
  <div id="headline"></div>
</mt:if>

これで任意の記事に目次を追加できるようになりました。

スムーススクロールを入れる

ページ内アンカーを使用したリンクなので、今回にあわせてスムーススクロールも実装しました。
こちらもGoogleで調べるとすぐ出てきますが、こんな感じです。

$(function(){
  $('a[href^="#"]').click(function(){
    var speed = 500;
    var href= $(this).attr("href");
    var target = $(href == "#" || href == "" ? 'html' : href);
    var position = target.offset().top;
    $("html, body").animate({scrollTop:position}, speed, "swing");
    return false;
  });
});

最初、このコードで上手くスクロールしてくれなかったのですが、その原因は利用しているjQueryがslim版だったことでした。
このブログはBootstrapを利用しているのですが、そこで読み込んでいる jQueryが jquery-3.4.1.slim.min.js だったので、この機会に jquery-3.5.1.min.js へ入れ替えました。

これで今回の作業がすべて完了です。


というわけで、これでまたこのブログも今っぽくなったかな、と(笑)
手軽に導入できたので満足です!

にしやま やすふみ

ウェブインテグレーション/コンサルティングの株式会社ジャクスタポジションで、代表とディレクターやってます。
Movable Typeとラーメン、ザンギ、酒が好き。
プロフィール詳細はこちら

アクセスの多い記事

現在、ウェブサイト移転に伴い同じ記事が複数回ランクインしています…ご了承ください。