views:

128

answers:

3

I am looking for a javascript on the fly "Table Of Contents" generation from HTML (with anchors).

Example:

<h1>First level1 heading</h1>
lorem ipsum
<h2>1a heading</h2>
lorem ipsum
<h2>1b heading</h2>
lorem ipsum
<h1>Second level1 heading</h1>
lorem ipsum

Should return something like

 First level1 heading   
   1a heading   
   1b heading 
 Second level1 heading

with the lines linked to the headings, and also the orignal html should be returned with anchors inserted.

Is there something included in one of the big javascript libraries or frameworks?

If none of them has, has someone seen a good JS module for this purpose?

+4  A: 

jQuery is your friend, with this plugin: table of contents. Home page is http://code.google.com/p/samaxesjs/

Tony Miller
A: 

This is a very simple problem that could be solved with a 10-20 line function. No framework required. Either walk the DOM with getElementsByTagName('h1'), getElementsByTagName('h2') or use regular expressions. Loading frameworks comes with performance implications and risks so I suggest not installing one for simple problems.

SpliFF
Using getElementsByTagName wouldn't work - since you would cluster each element type rather then getting them in the interleaved order... and there has been enough commentary about the perils of parsing HTML with regular expressions.
David Dorward
+1  A: 

Make it yourself, i wrote it :), hope it helps

add a div element as first child of body element and give an id as "tableOfContents"

and add the script below as last child of body element

<script>
    var el = document.getElementsByTagName("*") || [];
    var toc = "<ul>";
    var lvl = 1;
    for(var i=0;i<el.length;i++)
    {
        var ce = el[i];
        var tag = ce.tagName + "";
        var m = tag.match(/^h([1-5])$/i);
        if(m)
        {
            var n = Number(m[1]);
            if(lvl > n)
            {
                while(lvl-->n)toc+="</ul></li>";  
            }else if(lvl < n){
                while(lvl++<n)toc+="<li style='list-style:none'><ul>";
            }
            toc +=  '<li><a href="#toc_' + i + '">' + 
                    (ce.innerText || ce.text()) +
                    '</a></li>';
            var ta = document.createElement("div");
            ta.innerHTML = '<a name="toc_' + i + '" />';
            ce.insertBefore(ta, ce.firstChild);
        }
    }
    while(lvl-->1)toc+="</ul></li>";
    toc+="</ul>";
    document.getElementById("tableOfContents").
        innerHTML = toc;
</script>

this script will detects each H (1 to 5) and generates your table of contents

Tolgahan Albayrak