There are a
lot of approaches arround. Lets add one more to the pile:
Javascript
No need of jquery or other stuff. Just plain and simple vanilla js ;]
function TableOfContents(tocId, containerId) {
var toc = document.getElementById(tocId);
toc.innerHTML = "";
toc.className += " toc";
var container = containerId ? document.getElementById(containerId) : toc.parentElement;
var headings = [].slice.call(container.querySelectorAll('h1, h2, h3, h4, h5, h6'));
var closeLevel = function(e, levels) {
for (var i = 0; i < levels && e.parentElement && e.parentElement.parentElement; i++) {
e = e.parentElement.parentElement;
}
return e;
};
var createLiWithAnchor = function(anchor, heading) {
var li = document.createElement("li");
var a = document.createElement("a");
a.href = "#" + anchor;
a.textContent = heading.textContent;
li.appendChild(a);
heading.innerHTML = "<a name='" + anchor + "'>" + heading.textContent + "</a>";
heading.className += " no-decoration";
return li;
};
var prevLevel = 0;
var root, curr;
headings.forEach(function (heading, index) {
var tag = heading.tagName.toLowerCase();
var curLevel = parseInt(tag.replace(/[^\d]/i, ""));// get number from h1, h2, h3,... tags
var anchor = heading.textContent.replace(/\r?\n|\r/g, "").replace(/\s/, "_"); // remove all new lines and replace spaces with underscore
var li = createLiWithAnchor(anchor, heading);
if (curLevel > prevLevel) {
// open 1 ul and add 1 li
if (!curr) {
root = document.createElement("ol");
root.appendChild(li);
} else {
var ul = document.createElement("ul");
ul.appendChild(li);
curr.appendChild(ul);
}
} else if (curLevel === prevLevel) {
// add 1 new li next to current li
curr.parentElement.appendChild(li);
} else if (curLevel < prevLevel) {
// close n ul, add one 1 li as a sibling of the ancestor
var ancestor = closeLevel(curr, prevLevel - curLevel);
ancestor.parentElement.appendChild(li);
}
curr = li;
prevLevel = curLevel;
});
toc.appendChild(root);
}
If you are pasting this into blogger, the function must be XML escaped.
This site helped a lot
Css
So it looks a bit better.
/* ----- TOC ----- */
.toc {
background-color: #dadada;
border: gray solid 1px;
margin-bottom: 1em;
}
.toc .toc-title {
margin-left: 1em;
}
.post-body .no-decoration,
.post-body .no-decoration a {
text-decoration: none;
color: black;
}
Usage
Prepare a container
<div id="mytoc"></div>
Call the script
<script type="text/javascript">
TableOfContents("mytoc", "articleId");
</script>
If you using blogger just put the container div at the top of your post and omit the last parameter, the function will assume the article is the parent of the TOC container.
Result
0 comments :
Post a Comment