HeadingList
by mifeng
HTML
<h1>Heading 1</h1>
<h2>Heading 1.1</h2>
<h3>Heading 1.1.1</h3>
<h3>Heading 1.1.2</h3>
<h4>Heading 1.1.1.1</h4>
<h2>Heading 1.2</h2>
<h2>Heading 1.3</h2>
<h1>Heading 2</h1>
<h2>Heading 2.1</h2>
<h3>Heading 2.1.1</h3>
<h4>Heading 2.1.1.1</h4>
<h2>Heading 2.2</h2>
<h3>Heading 2.2.1</h3>
<h4>Heading 2.2.1.1</h4>
<h5>Heading 2.2.1.1.1</h5>
<h5>Heading 2.2.1.1.2</h5>
<h6>Heading 2.2.1.1.2.1</h6>
<h2>Heading 2.3</h2>
JavaScript
(function ($) {
"use strict";
function Node(tag, title) {
this.tag = tag;
this.title = title;
this.id = "";
this.child = [];
this.parent = null;
}
Node.prototype.addChild = function(node) {
this.child.push(node);
node.parent = this;
}
var list = [], current = null, prefix = 'heading-';
function insertNode(current, node) {
if (current === null) {
node.id = prefix + (list.length + 1);
list.push(node);
} else if (current.tag < node.tag) {
node.id = current.id + '-' + (current.child.length + 1);
current.addChild(node);
} else if (current.tag === node.tag) {
if (current.parent === null) {
node.id = prefix + (list.length + 1);
list.push(node);
} else {
node.id = current.parent.id + "-" +
(current.parent.child.length + 1);
current.parent.addChild(node);
}
} else {
insertNode(current.parent, node);
}
}
$("h1,h2,h3,h4,h5,h6").each(function() {
var $this = $(this),
node = new Node($this.prop("tagName"), $this.text());
insertNode(current, node);
$this.append("<span id='" + node.id + "'></span>");
current = node;
});
function dump(arr) {
var result = "";
for (var i = 0; i < arr.length; i++) {
result += "<li><a href='#" + arr[i].id + "'>" +
arr[i].title + "</a>";
if (arr[i].child.length > 0)
result += "<ul>" + dump(arr[i].child) + "</ul>";
result += "</li>";
}
return result;
}
$("body").prepend("<div><ul>" + dump(list) + "</ul></div>");
})(jQuery);