Flexible plugin for nested table of contents
My partner saw the search results page for this blog and, always on the lookout for a way to improve things, suggested that it would benefit from a table of contents at the top. I could do this with Wordpress, of course, but it sounded like a good idea for a jQuery plugin, too.
A little googling showed that there were a couple of existing solutions, but there were two things I wanted that they didn't seem to offer:
- the ability to select via selectors exactly which elements would be included (i.e.,
#content h2instead of justh2) - the ability to nest the lists of sections to reflect the hierarchy of the page
After puzzling a bit over how to get a list of selected elements in the order they appear in the document (see note below), I wrote my own plugin.
Usage:
var $toc = $.toc('#content h1, h2, h3.foo');
So you can do:
$.toc('h1,h2,h3').prependTo('body').attr('id','toc');
Note
$('h1,h2') will return a jQuery object containing all the h1's in a document, followed by all the h2's in a document: h1 h1 h1 h2 h2 h2. I needed all the h1's and h2's in the document in the order they appeared; so, perhaps, h1 h1 h2 h2 h1 h2 h2.
The obvious-in-hindsight answer:
$('h1,h2').addClass('selectedElements'); var selectedElements = $('.selectedElements');
Of course, the bad thing about this is that, on pages with lots of elements, it's going to be slow. Any better suggestions?
December 26th, 2007 at 5:37 pm
[...] Flexible plugin for nested table of contents [...]
December 29th, 2007 at 12:13 pm
Nice plugin. Well done
March 2nd, 2008 at 12:41 pm
Nice plugin! I made two changes though. I wrapped the child list in it’s own element, which is a a little more semantically correct. And I adjusted the regex to this:
var anchor = text.replace(/([^A-Za-z])/g,”);
That way, only text characters remain.
May 16th, 2008 at 5:15 am
Nice plug-in. Almost exactly what I needed. I might even be able to understand some of the magic if I try hard enough!
June 9th, 2008 at 11:15 am
Thanks, works great
June 9th, 2008 at 12:50 pm
… could you suggest how to only create the toc *if* it found some matching headings? Currently it outputs an empty ul.
Thanks again.