ナビゲーションの自動生成

目次を作成

手動だと

よくページ上部にそのページ内の特定のセクションにジャンプするためのリンク群が置かれていますが、すべてそれを手作業で行なおうとすると、非常に手間が掛かります。そういったユーザインタフェースな部分はHTMLの本質的なものではないので、本文に直接組み込んでいると文書の再利用性が低くなるかもしれません。

自動で生成

そういった面倒な作業は、プログラムに任せてしまうのが一番です。 HTML文書自体にはヘッダに一行を加えるだけですので、殆ど邪魔にはなりません。

サンプル

ページの一番上に目次を作成します。 このサンプルではボタンを押したときに生成していますが、ページ読みこみ時にで生成するのが理想的でしょう。

プログラム

汎用性

ページ一つ一つのためにプログラムしていたのではかえって手間が掛かるだけで意味が無いので、あらゆるHTML文書で有効なプログラムにします。

ここでは、特定のレベルの見出しを DOM によって抽出することにします。 使用する言語は JavaScirpt(ECMA-262) です。

ソースコード

function makeIndex(){
    var objHeading = document.getElementsByTagName("h2");
    var objNaviList = document.createElement("ul");
    for(i=0;i<objHeading.length;i++){
        objListItem = document.createElement("li");
        objListAnchor = document.createElement("a");
        objListAnchor.setAttribute("href","#index" + i);
        objHeadText = objHeading[i].firstChild.nodeValue;
        objListText = document.createTextNode(objHeadText);
        objListAnchor.appendChild(objListText);
        objListItem.appendChild(objListAnchor);
        objNaviList.appendChild(objListItem);
        objHeading.item(i).id = "index" + i;
    }
    document.body.insertBefore(objNaviList,document.body.firstChild);
}
if(document.getElementById){window.onload = makeIndex;}

DOM Level1 に対応しているブラウザなら、きちんと動作するはずです。

スタイルを適用

クラスを設定

そのままではナビゲーションリンクである事が分かり難いかもしれないので、CSSによってスタイルを変更してやると良いかもしれません。直接 style 属性に含めても良いのですが、ここでは Nametoken(class名)を与えることにします。

var objNaviList = document.createElement("ul");」 の次の行に 「objNaviList.class = "クラス名";」 を加えます。その後は外部CSSか何かでスタイルを適用すればOKです。この例では

.navilist{
  background-color: #ffe;
  border: #fc9 3px double;
  list-style: disc inside none;
}

というスタイルを適用しています。

画面上に固定してみる

Mozilla や Nestcape6以降、Opera6以降では 画面上の一定の位置にナビゲーションを固定する事が出来ます。 スクロールさせても位置は変わりません。

.navilist{
  position :fixed;
  left: 0;
  top: 0;
}

ずっとくっ付いてくるとなかなかに邪魔なので、任意に消せるような工夫を凝らしてみても良いでしょう。

セレクトボックスで表示

改造にあたって

IE では appendChild() メソッドで追加したノードではイベントが発生しないというバグがあるため、セレクトボックスによる目次を実現するには IE 独自拡張の innerHTML プロパティを使うしかありません。

DOMの良さを活かせず、非常に汚いソースになるので、あまりお奨めできません。 しかも、この方法は IE しか通用しません。

サンプル

プログラム

function makeIndex(){
    var objHeading = document.getElementsByTagName("h2");
    var objNaviList = document.createElement("select");
    var txtOpt = '<select onchange="jumpAnchor()"><option>--簡易目次--</option>';

    for(i=0;i<objHeading.length;i++){
        objHeadText = objHeading[i].firstChild.nodeValue;
        txtOpt += '<option>'+ objHeadText +'';
        objHeading.item(i).id = "index" + i;
    }
    txtOpt += "</select>";
    objNaviBox = document.createElement("div");
    objNaviBox.id = "navibox";
    document.body.insertBefore(objNaviBox,document.body.firstChild);
    objNaviBox.innerHTML = txtOpt;
}

function jumpAnchor(){
    var intOpt = document.getElementById("navibox").firstChild.selectedIndex;
    intOpt--;
    if(intOpt>=0){
        var strHash = "#index" + intOpt;
        location.href(strHash);
    }
}

サンプルでは無限に出てきますが、実際は onload のタイミングで出すのであまり問題ではありません。