效果
效果如下,点击标题跳到具体章节:
实现
1.创建TOC容器,目录生成在TOC中,例子中目录生成在body最上方:
//查找TOC容器,不存在时在文档开头创建 var toc = document.getElementById("TOC"); if(!toc){ toc = document.createElement("div"); toc.id = "TOC"; document.body.insertBefore(toc, document.body.firstChild); }
2. 查找标题元素
//查找所有的标题元素 var headings; if(document.querySelectorAll){ headings = document.querySelectorAll("h1,h2,h3,h4,h5,h6"); //jQuery的选择器即是基于querySlectAll }else{ headings = findHeadings(document.body,[]); } //fundHeadings function findHeadings(root, sects){ for(var c = root.firstChild; c!=null; c = nextSibling){ if(c.nodeType != 1){ //不是Element节点 continue; } if(c.tagName.length == 2 && c.tagName.charAt(0) == "H"){ sects.push(c); } } return sects; }
3. 创建章节号
//初始化数组保持跟踪章节号 var sectionNumbers = [0,0,0,0,0,0]; for(var h = 0; h<headings.length; h++){ var heading = headings[h]; //跳过TOC容器中的标题元素 if(heading.parentNode == toc){ continue; } //判断标题的级别 var level = parseInt(heading.tagName.charAt(1)); if(isNaN(level) || level <1 || level > 6){ continue; } sectionNumbers[level-1]++; // 对于该标题级别增加sectionNumbers对应的数字 for(var i = level; i < 6; i++){ //将标题级别比其低的置为0 sectionNumbers[i] = 0; } var sectionNumber = sectionNumbers.slice(0,level).join(".");//生成组合章节号,例如2.3.1
4、为文中标题添加样式并且将其用增加链接,以便点击目录能够跳到标题
//为标题级别添加章节号,放置在<span>标签中,并添加样式 var span = document.createElement("span"); span.className = "TOCSectNum"; span.innerHTML = sectionNumber; heading.insertBefore(span, heading.firstChild); //为标签添加锚,以便添加链接 var anchor = document.createElement("a"); anchor.name = "TOC" + sectionNumber; heading.parentNode.insertBefore(anchor, heading); anchor.appendChild(heading);
5、为目录添加锚,将目录与标题对应
//为目录增加链接 var link = document.createElement("a"); link.href = "#TOC" + sectionNumber; link.innerHTML = heading.innerHTML; //将链接放置在DIV中 var entry = document.createElement("div"); entry.className = "TOCEntry TOCLevel" + level; entry.appendChild(link); toc.appendChild(entry);
6、目录css样式
#TOC{ border: solid pink 2px; border-radius: 10px; margin: 10px; padding:10px; line-height:25px; border:solid 1px #dbe4eb; border-top-color:#00A3DE; border-top-width:15px; border-bottom-width:1px; background:#fff; border-radius:20px; } .TOCList{ min-height:30px; border-bottom:dashed 1px #dbe4eb; overflow:hidden;zoom:1;} .TOCEntry{ font-family:sans-serif; } .TOCEntry a{ text-decoration: none; color: #00A3DE; } .TOCLevel1 { font-size: 16pt; } .TOCLevel2{ font-size: 12pt; margin-left: .4in; } .TOCLevel3{ font-size: 10pt; margin-left: .6in; } .TOCLevel4{ font-size: 10pt; margin-left: 0.8in; } .TOCLevel5{ font-size: 10pt; margin-left: 1.0in; } .TOCLevel6{ font-size: 10pt; margin-left: 1.2in; } .TOCSectNum:after{ content: ". "; }
完成例子
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <style> #TOC{ border: solid pink 2px; border-radius: 10px; margin: 10px; padding:10px; line-height:25px; border:solid 1px #dbe4eb; border-top-color:#00A3DE; border-top-width:15px; border-bottom-width:1px; background:#fff; border-radius:20px; } .TOCList{ min-height:30px; border-bottom:dashed 1px #dbe4eb; overflow:hidden;zoom:1;} .TOCEntry{ font-family:sans-serif; } .TOCEntry a{ text-decoration: none; color: #00A3DE; } .TOCLevel1 { font-size: 16pt; } .TOCLevel2{ font-size: 12pt; margin-left: .4in; } .TOCLevel3{ font-size: 10pt; margin-left: .6in; } .TOCLevel4{ font-size: 10pt; margin-left: 0.8in; } .TOCLevel5{ font-size: 10pt; margin-left: 1.0in; } .TOCLevel6{ font-size: 10pt; margin-left: 1.2in; } .TOCSectNum:after{ content: ". "; } </style> </head> <body> <h1>第一章</h1> <h2>第一小节</h2> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <h3>第一讲</h3> <h4>4级标题1</h4> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <h5>5级标题1</h5> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <h6>6级标题1</h6> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <h6>6级标题1</h6> <h5>5级标题1</h5> <h4>4级标题2</h4> <h3>第二讲</h3> <h1>第二章</h1> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <h2>第一小节</h2> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <h3>第一讲</h3> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <h3>第二讲</h3> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <h1>第三章</h1> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <p>##############################################################</p> <h2>第一小节</h2> <h3>第一讲</h3> <h3>第二讲</h3> <script> /** * 工具函数onLoad,当文档载入完成时调用一个函数 */ function onLoad(f){ if(onLoad.loaded){ window.setTimeout(f,0); }else if(window.addEventListener){ window.addEventListener("load",f,false); }else if(window.attachEvent){ window.attachEvent("onload",f); } } onLoad.loaded = false; onLoad(function(){ onLoad.loaded = true; }); /** * 生成目录 */ onLoad(function(){ //查找TOC容器,不存在时在文档开头创建 var toc = document.getElementById("TOC"); if(!toc){ toc = document.createElement("div"); toc.id = "TOC"; document.body.insertBefore(toc, document.body.firstChild); } //查找所有的标题元素 var headings; if(document.querySelectorAll){ headings = document.querySelectorAll("h1,h2,h3,h4,h5,h6"); }else{ headings = findHeadings(document.body,[]); } //fundHeadings function findHeadings(root, sects){ for(var c = root.firstChild; c!=null; c = nextSibling){ if(c.nodeType != 1){ //不是Element节点 continue; } if(c.tagName.length == 2 && c.tagName.charAt(0) == "H"){ sects.push(c); } } return sects; } //初始化数组保持跟踪章节号 var sectionNumbers = [0,0,0,0,0,0]; for(var h = 0; h<headings.length; h++){ var heading = headings[h]; //跳过TOC容器中的标题元素 if(heading.parentNode == toc){ continue; } //判断标题的级别 var level = parseInt(heading.tagName.charAt(1)); if(isNaN(level) || level <1 || level > 6){ continue; } sectionNumbers[level-1]++; // 对于该标题级别增加sectionNumbers对应的数字 for(var i = level; i < 6; i++){ //将标题级别比其低的置为0 sectionNumbers[i] = 0; } var sectionNumber = sectionNumbers.slice(0,level).join(".");//生成组合章节号,例如2.3.1 //为标题级别添加章节号,放置在<span>标签中,并添加样式 var span = document.createElement("span"); span.className = "TOCSectNum"; span.innerHTML = sectionNumber; heading.insertBefore(span, heading.firstChild); //为标签添加锚,以便添加链接 var anchor = document.createElement("a"); anchor.name = "TOC" + sectionNumber; heading.parentNode.insertBefore(anchor, heading); anchor.appendChild(heading); //为目录增加链接 var link = document.createElement("a"); link.href = "#TOC" + sectionNumber; link.innerHTML = heading.innerHTML; //将链接放置在DIV中 var entry = document.createElement("div"); entry.className = "TOCList TOCEntry TOCLevel" + level; entry.appendChild(link); toc.appendChild(entry); } }); </script> </body> </html>