Auto-generating a TOC with jQuery 5 November 06
I’ve been playing with jQuery recently after hearing plenty of buzz, and being amazed at how lean the code can be compared to using traditional JavaScript development.
The jQuery library itself is pretty small, only 51kb compared to the more traditional combination of Prototype (v1.5.0 is 62kb) and the effects and DOM manipulation library script.aculo.us (ranging from 2kb – 33kb depending on which scripts you use), but the functionality isn’t lacking.
I’ve been working recently with some fairly long pages full of copy and their relevant headings. The thing this page needed was a Table of Contents at the top for easier navigation rather than all this scrolling.
The copy was maintained by the end users via a CMS and output controlled via templates, so there was little I could do server side but seemed to be the perfect opportunity to test out jQuery’s DOM manipulation.
So on with the code..
jQuery waits for the document to be loaded before the script is fired, this is done by registering the ready event:
$(document).ready(function() {
//code will go here
}
Then we need to insert a ‘Table of Contents’ header in the 'toc' placeholder DIV, then an empty ordered list ready to fill with the titles:
$("#toc").prepend("<h2>Table of Contents<\/h2> »
<ol id=\"genTOC\"><\/ol>");
Now we need to look in the 'content' DIV and for every title found we need to insert a new entry in the Table of Contents list:
$("#content h2").each(function(i) {
$("#toc ol").append("<li><a href=\"#" + »
$(this).id() + "\">" + $(this).html() + "<\/a><\/li>");
});
And that’s it! Here’s a demo of it in action.
If you are running the Firefox Web Developer extention you can disable JavaScript and test to see how gracefully it degrades to boot!
That’s very cool! Although it does require that you setup your headers with id’s in advance. How would you dynamically assign id’s to headers with jQuery?
— Jeroen Coumans Apr 10, 14:06 #
Hi Jerome,
If you wanted to create the ID’s on the fly (remember they have to be unique) you can use the .attr() function. Try something like this, although the generated link doesn’t seem to work in FF?
Update: Now works cross browser. Instead of escaping the title's spaces when forming the ID, I now simply replace them with hyphens.
http://jameswragg.com/demos/autogentoc/index-alt.htm
Cheers,
James
— James Wragg Apr 17, 16:32 #