続、目次フレームを自動生成する
あと、目次フレームを自動生成するの toc.js の諸々を修正しました。主な修正点はオブジェクトメンバの実装をリテラル記法にして見やすくしたのと、自動生成される ID の番号の階層がおかしかった点を改善しました。
あと、汎用性を考慮して初期化ハンドラを自動で登録しないようにしたのでwindow.onload を待たずに処理を開始するを使ってもいいかも。
<script type="text/javascript" src="loadlistener.js"></script> <script type="text/javascript" src="toc.js"></script> <script type="text/javascript">//<![CDATA[ LoadListener.onload = function () { toc.create(); }; //]]></script>
var toc = function () { // // Node クラス // // コンストラクタ function Node (element, level, idprefix, sindex) { this.element = element; this.level = level; this.idprefix = idprefix; this.sindex = sindex; this.firstChild = null; this.nextSibling = null; if (element && !element.id) element.id = this.idprefix + "-" + this.sindex; } // // Node クラスの実装 // // 子要素追加 Node.prototype = { append: function (element, level) { if (this.nextSibling != null) { this.nextSibling.append (element, level); return; } var childId = this.idprefix; if (this.level > 0) childId += "-" + this.sindex; switch (level - this.level) { case 0: this.nextSibling = new Node (element, level, this.idprefix, this.sindex + 1); break; case 1: if (this.firstChild == null) this.firstChild = new Node (element, level, childId, toc.baseIndex); else this.firstChild.append (element, level); break; default: if (this.firstChild == null) this.firstChild = new Node (null, this.level + 1, childId, toc.baseIndex); this.firstChild.append (element, level); break; } }, // 目次を作成する createIndex: function (listTagName) { var li = document.createElement ("li"); if (this.element != null) { var ancher = document.createElement ("a"); ancher.setAttribute ("href", "#" + this.element.id); var text = document.createTextNode (this.element.textContent || this.element.innerText); ancher.appendChild (text); li.appendChild (ancher); } if (this.firstChild) { var list = document.createElement (listTagName); var node = this.firstChild; while (node != null) { list.appendChild (node.createIndex (listTagName)); node = node.nextSibling; } li.appendChild (list); } return li; } }; // // toc のプライベートメソッド // // 要素を走査して木構造を作る var scanElements = function (idprefix) { var elements = document.getElementsByTagName ("*"); var root = new Node (null, 0, idprefix, 0); for (var i = 0; i < elements.length; i ++) { var element = elements [i]; if (element.nodeName.match (/^h([1-9])$/i)) { var number = RegExp.$1 - 0; root.append (element, number); } } return root; }; // 木構造から目次を作る var createIndex = function (root, listTagName) { var list = document.createElement (listTagName); var node = root.firstChild; while (node != null) { list.appendChild (node.createIndex (listTagName)); node = node.nextSibling; } return list; }; // // toc オブジェクトを返す // return { listtag: "ul", tocId: "toc", defaultIdPrefix: "hedding", baseIndex: 1, create: function () { var root = scanElements (this.defaultIdPrefix); var tocelem = document.createElement ("div"); tocelem.id = this.tocId; tocelem.appendChild (createIndex (root, this.listtag)); document.body.appendChild (tocelem); } } } ();
トラックバック
- このエントリーにトラックバック:
- http://frog.raindrop.jp/cgi-bin/mt/mt-tb.cgi/2473
コメント