ブログなんかでよくみかける記事の目次機能ですが、プラグインを使うことで比較的簡単に実装することができます。ただ要件的に制約があったり、カスタマイズが難しい場合もあるかもしれません。
そこで、今回はプラグイン無しで目次機能を実装してみたいと思います。ちなみに表示だけでなく目次の項目をクリックすることで該当する見出しまでページの先頭が移動します。
まずはHTMLから、今回は目次自体をdlタグで実装していますが、リストであれば何でもいいかと思います。目次の項目はJavaScriptで自動生成していくので空にしておきます。
【HTML】※一部省略
<dl id="index"> <dt>目次</dt> </dl> <article id="content"> <h1>見出しタイトル1 </h1> <p>本文テキスト 本文テキスト 本文テキスト 本文テキスト 本文テキスト </p> <h2>見出しタイトル2 </h2> <p>本文テキスト 本文テキスト 本文テキスト 本文テキスト 本文テキスト </p> <h3>見出しタイトル3 </h3> <p>本文テキスト 本文テキスト 本文テキスト 本文テキスト 本文テキスト </p> </article>
次にjQueryでコンテンツ内の見出しをピックアップして、そこから目次を自動生成してくれるようにしていきます。まずは、目次番号を付与するための基準となるカウントナンバーを変数に入れておきます。そして、コンテンツ内の見出し(h1〜h6)全てをセレクタで指定し、それぞれに関数を適用させます。
【javascript】
$(function(){ var countId = 1 $("#content h1,#content h2,#content h3,#content h4,#content h5,#content h6").each(function(){ var ttl = $(this).text(); var lv = this.nodeName.toLowerCase(); this.id = 'ttl-' + countId; countId ++; $("#index").append('<dd class="lv_'+lv+'"><a href="#'+this.id+'">'+ttl+'</a></dd>'); }); });
関数内では、まず見出し要素が持つテキストを抽出し変数に格納します。そして、その要素の見出しレベルも同じく変数に格納しておきます。
次に、目次番号をidとして目次項目のリンク先に設定するようにしておきます。目次の数が連番で付与されるようになります。
そして目次の全体であるdl要素内に目次項目(dd要素)を追加していくようにします。ここではclassにそれぞれの見出し要素のレベルを、アンカーリンクに目次番号を付与する仕組みになっています。ここで見出し要素のレベル別にclassを付与することで、見出しの種類別にスタイルを設定できるので便利です。
今回はCSSは省略していますが、下記のサンプルでは簡単に設定していますので参考に。実際に実装するとこんな感じになります。
See the Pen Automatic table of contents by designsupply (@designsupply) on CodePen.
過去記事「jQueryで実装するページ内アンカーリンクとページトップへのスクロール」で紹介しているようなアンカースクロールにアニメーションを使うとユーザビリティが上がるのではないでしょうか。WordPressではプラグインも用意されているようですが、オリジナルで実装したい場合には使えるのではないでしょうか。