目次の自動生成を行う jQuery.exTOC.js

exTOC は、ページ内の Hn 要素(h1 - h6)に対し、ページ内リンク付きの目次コンテンツを自動生成する jQuery プラグインです。

以下のような特徴があります。

  • 目次 / Hn 要素に対する付番機能
  • ページ内リンクのスムーススクロール
  • 高いカスタマイズ性

以下は exFixed Plugin / Easing Plugin を併用したデモです。

導入方法


上記 js ファイルをダウンロードしヘッダー定義内で下記順で jquery.js / extoc.js を読み込みます。

<script type="text/javascript"  src="path/jquery.js"></script>
<script type="text/javascript"  src="path/extoc.js"></script>

目次コンテンツ挿入先の基準位置となる要素を jQuery セレクタで取得し、exTOC() メソッドを実行すると、目次の生成と挿入が行われます

jQuery(function($){
	$('h2').exTOC({
		headFrom : 3,
		headTo : 5,
		insertMethod : 'after'
	});
});	

上記例では、h3 / h4 / h5 要素を対象に目次を生成し、h2 要素の後方に(弟要素として)目次を挿入します。

動作環境

以下のブラウザ / jQuery のバージョンで動作確認済みです。

Browser
jQuery
ver 1.2.6 / 1.3

使用例

以下サンプルページに、exTOC を適用してみます。

h1 がサイト名、h2 が記事タイトルの構成なので h3 以降を目次化の対象とします。

目次コンテンツを生成する

var toc = $('h2').exTOC({
	headFrom : 3,
	headTo : 5,
	insertMethod : 'after'
});
toc.getTOC().before('<h3>Index</h3>')

h2 要素 を 基準要素として取得し、exTOC メソッドを実行しています。

headFrom / headTo
headFrom / headTo は目次対象とする Hn 要素の範囲を指定します。例では h3 〜 h5 を目次の対象としています。
insertMethod
insertMethod は基準ノード( h2 )に対しどの位置に目次コンテンツを挿入するかを指定します。例では 'after' としてるので、 h2 要素 の後方に(弟要素として)挿入されます。他にも before / prepend / append 等が指定できます。
exTOC オブジェクト
exTOC() メソッドを実行すると exTOC オブジェクト が返却値として返されます。例では変数 toc に格納しています。
getTOC()
exTOC オブジェクトの getTOC() メソッドを実行すると、目次コンテンツを jQuery オブジェクト形式で取得できます。例では before メソッドを使用し、取得した目次コンテンツの手前に(兄要素として) '<h3>Index</h3>' を挿入しています。

Hn 要素に対しても付番する

var toc = $('h2').exTOC({
	headFrom : 3,
	headTo : 5,
	insertMethod : 'after',
	numberingHead : true
});

numberingHead
numberingHead を true にすると Hn 要素に対しても付番が行われます。

付番の表示レベルを抑止する

var toc = $('h2').exTOC({
	headFrom : 3,
	headTo : 5,
	insertMethod : 'after',
	numberingHead : true,
	numberingFrom : 2,
	numberingTo : 3
});

numberingFrom / numberingTo
numberingFrom / numberingTo を指定すること付番の表示レベルを抑止できます。例では 2 〜 3 としてるので、 左から数えて 1 桁目の表示が抑止されます。
デモページでは 大分類に相当する h3 の付番はせず CSS で見た目のデザインを整えています。

jQuery exFixed Plugin で目次の表示位置を固定する

var toc = $('h2').exTOC({
	headFrom : 3,
	headTo : 5,
	insertMethod : 'after',
	numberingFrom : 2,
	numberingTo : 3
});
toc.getTOC().exFixed({
	width:200,
	top:$('h2').position().top,
	right:16
});
$('body').css({
	'margin-right':232
})

getTOC() メソッドで目次コンテンツを取得し、exFixed() メソッドで目次コンテンツの表示位置を固定してます。

exFixed() メソッドは IE6 でも position:fixed を可能にする jQuery プラグインで、これによりブラウザの種類を気にすることなく position : fixed が扱えるようになります。詳しくは以下の記事をご覧ください。

記事タイトルと表示位置の高さを合わせるために h2 要素より position().top を取得し、top パラメータに指定してます。

また、目次を固定表示すると記事本文が目次の下に隠れてしまうので、目次コンテンツの幅分 body 要素の margin を調整しています。

jQuery Easing Plugin でスムーススクロールさせる

jQuery Easing Plugin を導入するといろいろな種類のエフェクトでスムーススクロールさせることができます。


各エフェクトのデモはjQuery 日本語リファレンスの以下のページで確認できます。


気にいったエフェクトのみを取り込みたい場合は、jquery.easing.1.3.jsの該当するエフェクト定義の部分のみ自前のソースにコピペすることで可能です。

例えば easeOutBounce というエフェクトを使用したい場合は、JSON 形式で定義されているコードを以下のように整形してコピーします。

jQuery.easing.easeOutBounce = function (x, t, b, c, d) {
	if ((t/=d) &lt; (1/2.75)) {
		return c*(7.5625*t*t) + b;
	} else if (t &lt; (2/2.75)) {
		return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
	} else if (t &lt; (2.5/2.75)) {
		return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
	} else {
		return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
	}
}

exTOC() メソッドの easing パラメータに該当するエフェクト名を指定します。また、speed パラメータでエフェクトの速度を指定できます。

$('h2').exTOC({
	・・・
	easing : 'easeOutBounce',
	speed : 1000
});

目次コンテンツのマークアップ

目次コンテンツのマークアップは、以下のような ul / li の入れ子構成になっています。

各要素の class 名には、階層毎の枝番が振られてるので CSS による柔軟なデザインが可能です。

// 1 階層目
<ul class="ex-toc ex-toc-1">
	<li class="ex-toc ex-toc-1">
		<a class="ex-toc ex-toc-1">
			<span class="ex-toc-label ex-toc-label-1">1.<span>
			<span class="ex-toc-text ex-toc-text-1">Overview</span>
		</a>
	</li>
	<li class="ex-toc ex-toc-1">
		<a class="ex-toc ex-toc-1">
			<span class="ex-toc-label ex-toc-label-1">2.<span>
			<span class="ex-toc-text ex-toc-text-1">Compatibility</span>
		</a>
		// 2 階層目
		<ul class="ex-toc ex-toc-2">
			<li class="ex-toc ex-toc-2">
				<a class="ex-toc ex-toc-2">
					<span class="ex-toc-label ex-toc-label-2">2.1.<span>
					<span class="ex-toc-text ex-toc-text-2">ver 1.2.6</span>
				</a>
			</li>
		</ul>
	</li>
	… (省略) …
</ul>

リファレンス

exTOC() メソッドのパラメータ

exTOC( parameter ) : exTOC オブジェクト
parameter を JSON 形式で指定できます。返却値は exTOC オブジェクト を返します。
parameter default description
contents 'body' Hn 要素抽出の走査範囲を指定します。jQuery オブジェクトで指定することも可能です。

例) 'div.contents' or $('div.contents')
headFrom 3 目次化対象とする Hn 要素の開始範囲を指定します。
headTo 5 目次化対象とする Hn 要素の終了範囲を指定します。
index true false とした場合、目次の生成を行いません。
目次は不要で Hn 要素に対する付番のみ行いたい場合に false を指定し
numberingHead を true にします。
numbering true false とした場合、付番を行いません。
numberingHead false true とした場合、Hn 要素に対しても付番を行います。
numberingFrom 1 付番表示の開始レベルを指定します。

例)numberingFrom:2 の場合 1.2.3 → 2.3 と表示される
numberingTo 6 付番表示の終了レベルを指定します。

例)numberingTo:2 の場合 1.2.3 → 1.2 と表示される
insertMethod 'prepend' 基準ノードに対しての挿入方法を指定します。


'prepend' 基準ノード内に前方挿入
'append' 基準ノード内に後方挿入
'before' 基準ノード外に前方挿入
'after' 基準ノード外に後方挿入

link true false とした場合ページ内リンクを行いません。
smooth true false とした場合、スムーススクロールを行いません。
easing 'swing' スムーススクロールの easing を指定できます。デフォルトでは 'swing','linear' から選べますが、easing plugin 等で拡張してる場合は、拡張した easing 名も指定できます。
speed 'slow' スムーススクロールのスピードを指定できます。'slow','fast' の他に数値でも指定できます。

exTOC オブジェクト のメソッド

exTOC() メソッドを実行すると返却値として、exTOC オブジェクトが返されます。exTOC オブジェクトは以下メソッドを持ちます。

target() メソッド
exTOC() メソッドの基準ノードを返します。
var head = $('h2');
alert(head.exTOC().target() == head ); //true
getTOC() メソッド
生成された目次コンテンツを jQuery オブジェクトで返します。
例えば、目次コンテンツの外枠を実線で囲むには以下のようにします。
$('h2').exTOC().getTOC().css('border','solid 1px red');

最後に

最近会社でリファレンスマニュアルを作る機会があり、ページ内リンクを手書きするのが面倒だったので作ってみました。

リファレンスマニュアルのような縦長ページの場合、exFixed の併用例のように目次位置を固定化すると利便性があがるかと思います。

実装の方は、各 Hn 要素とその配下要素でグルーピングされた jQuery オブジェクトを取得 & each する exHeadEach メソッドというのが定義されていて、これが実装上のキモになっています。
exHeadEach に対し callback 関数を与えて目次生成処理等を追加する構成になっています。
(応用すれば Hn 要素ベースなアコーディオンなども作れるかと思います。需要なさそうですが..)