文章或博客自动生成章节目录索引(支持三级)的实现代码


Posted in Javascript onMay 10, 2020

自动生成章节目录索引(只支持一级)

一个好的博文除了博文的质量要好以外,好的组织结构也能让读者阅读的更加舒服与方便,我看园子里面有一些园友的博文都是分章节的,并且在博文的前面都带有章节的目录索引,点击索引之后会跳转到相应的章节阅读,并且还可以回到目录顶端,其中 Fish Li 的博文就是这种组织,当然这种结构如果是在写博文的时候人工设置那是非常麻烦的,无疑是增加了写作人的工作量。如果能自动生成章节索引岂不是节省了一大堆工作量。本来想通过FireBug看看Fish Li源码是怎么实现的,但是好像js是加密过的。那我就自己动手了,其实也没多少代码,很简单。

<script language="javascript" type="text/javascript">
//生成目录索引列表
function GenerateContentList()
{
  var jquery_h3_list = $('#cnblogs_post_body h3');//如果你的章节标题不是h3,只需要将这里的h3换掉即可
  if(jquery_h3_list.length>0)
  {
    var content = '<a name="_labelTop"></a>';
    content  += '<div id="navCategory">';
    content  += '<p style="font-size:18px"><b>阅读目录</b></p>';
    content  += '<ul>';
    for(var i =0;i<jquery_h3_list.length;i++)
    {
      var go_to_top = '<div style="text-align: right"><a href="#_labelTop" rel="external nofollow" rel="external nofollow" >回到顶部</a><a name="_label' + i + '"></a></div>';
      $(jquery_h3_list[i]).before(go_to_top);
      var li_content = '<li><a href="#_label' + i + '" rel="external nofollow" rel="external nofollow" >' + $(jquery_h3_list[i]).text() + '</a></li>';
      content += li_content;
    }
    content  += '</ul>';
    content  += '</div>';
    if($('#cnblogs_post_body').length != 0 )
    {
      $($('#cnblogs_post_body')[0]).prepend(content);
    }
  }  
}
GenerateContentList();
</script>

使用方法:登录到博客园之后,打开博客园的后台管理,切换到“设置”选项卡,将上面的代码,粘贴到 “页脚HTML代码” 区保存即可。

注意:上述js代码中提取的h3作为章节的标题,如果你的标题不是h3请在代码注释的地方自行修改。该代码除了在文章的最开始生成目录索引之外,还会在每一个章节最后右下角(也就是下一个章节标题的右上角)会生成一个“回到顶部”的链接,以方便读者回到目录。本篇文章的目录结构就是自动生成的效果,如果你觉得有用,就赶快试用一下吧。

自动生成三级目录

<script language="javascript" type="text/javascript">
//生成目录索引列表
function GenerateContentList()
{
  var jquery_h1_list = $('#cnblogs_post_body h1');
  if (jquery_h1_list.length == 0) { return; }
  if ($('#cnblogs_post_body').length == 0) { return; }

  var content = '<a name="_labelTop"></a>';
  content  += '<div id="navCategory">';
  content  += '<p style="font-size:18px"><b>阅读目录(Content)</b></p>';
  // 一级目录 start
  content += '<ul class="first_class_ul">';

  for (var i = 0; i < jquery_h1_list.length; i++)
  {
    var go_to_top = '<div style="text-align: right"><a href="#_labelTop" rel="external nofollow" rel="external nofollow" >回到顶部(go to top)</a><a name="_label' + i + '"></a></div>';
    $(jquery_h1_list[i]).before(go_to_top);

    // 一级目录的一条
    var li_content = '<li><a href="#_label' + i + '" rel="external nofollow" rel="external nofollow" >' + $(jquery_h1_list[i]).text() + '</a></li>';

    var nextH1Index = i + 1;
    if (nextH1Index == jquery_h1_list.length) { nextH1Index = 0; }
    var jquery_h2_list = $(jquery_h1_list[i]).nextUntil(jquery_h1_list[nextH1Index], "h2");
    // 二级目录 start
    if (jquery_h2_list.length > 0)
    {
      //li_content +='<ul style="list-style-type:none; text-align: left; margin:2px 2px;">';
      li_content += '<ul class="second_class_ul">';
    }
    for (var j = 0; j < jquery_h2_list.length; j++)
    {
      var go_to_top2 = '<div style="text-align: right"><a name="_lab2_'+ i + '_' + j + '"></a></div>';
      $(jquery_h2_list[j]).before(go_to_top2);
      // 二级目录的一条
      li_content +='<li><a href="#_lab2_'+ i +'_' + j + '" rel="external nofollow" >' + $(jquery_h2_list[j]).text() + '</a></li>';

      var nextH2Index = j + 1;
      var next;
      if (nextH2Index == jquery_h2_list.length) 
      {
        if (i + 1 == jquery_h1_list.length)
        {
          next = jquery_h1_list[0];
        }
        else
        {
          next = jquery_h1_list[i + 1];
        }
      }
      else
      {
        next = jquery_h2_list[nextH2Index];
      }
      var jquery_h3_list = $(jquery_h2_list[j]).nextUntil(next, "h3");
      // 三级目录 start
      if (jquery_h3_list.length > 0)
      {
        li_content += '<ul class="third_class_ul">';
      }
      
      for (var k = 0; k < jquery_h3_list.length; k++)
      {
        var go_to_third_Content = '<div style="text-align: right"><a name="_label3_' + i + '_' + j + '_' + k + '"></a></div>';
        $(jquery_h3_list[k]).before(go_to_third_Content);
        // 三级目录的一条
        li_content += '<li><a href="#_label3_' + i + '_' + j + '_' + k + '" rel="external nofollow" >' + $(jquery_h3_list[k]).text() + '</a></li>';
      }
      
      if (jquery_h3_list.length > 0)
      {
        li_content += '</ul>';
      }
      li_content += '</li>';
      // 三级目录 end
    }
    if (jquery_h2_list.length > 0)
    {
      li_content +='</ul>';
    }
    li_content +='</li>';
    // 二级目录 end

    content += li_content;
  }
  // 一级目录 end
  content += '</ul>';
  content += '</div>';

  $($('#cnblogs_post_body')[0]).prepend(content);
}

GenerateContentList();
</script>
levels of contents

如何使用(How to Use)

把上述JS代码复制到“页脚Html代码”里。

文章或博客自动生成章节目录索引(支持三级)的实现代码

在写博客的时候,给每个章节的标题设置“标题1”或“标题2”或“标题3”格式。

文章或博客自动生成章节目录索引(支持三级)的实现代码

然后一切就绪,欣赏效果吧。

示例(Demo)

三水点靠木小编注:为了seo考虑,不建议大量用h1,一个页面可以存在多个h2,h3,h4,所以三水点靠木网站采用的是h2,h3,h4实现三级目录。

补充:

三水点靠木小编从别的地方看到的相关文章可以当个参考

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <style>
    * {
      margin: 0;
      padding: 0;
      word-break: break-all;
    }
    #toc {
      width: 200px;
      position: fixed;
      left: 0;
      top: 0;
    }
    #toc a.active {
      color: red;
    }
    #content {
      margin-left: 200px;
    }
  </style>
  <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
  <script>
    $(document).ready(function () {
      for (var i = 0; i < 50; ++i) {
        $(".seg-content").append("<p>一个段落而已</p>")
      }

      (function () {
        var segs = [];
        $(".seg-begin").each(function (idx, node) {
          segs.push(node)

          var link = $("<a></a>").attr("href", "#" + $(node).attr("name")).html($(node).children("h1").html())
          if (!idx) {
            link.addClass("active")
          }
          var row = $("<li></li>").append(link)
          $("#toc ul").append(row)
        })

        $(window).bind("scroll", function() {
          var scrollTop = $(this).scrollTop()

          var topSeg = null
          for (var idx in segs) {
            var seg = segs[idx]
            if (seg.offsetTop > scrollTop) {
              continue
            }
            if (!topSeg) {
              topSeg = seg
            } else if (seg.offsetTop >= topSeg.offsetTop) {
              topSeg = seg
            }
          }
          if (topSeg) {
            $("#toc a").removeClass("active")

            var link = "#" + $(topSeg).attr("name")
            console.log('#toc a[href="' + link + '" rel="external nofollow" rel="external nofollow" ]')
            $('#toc a[href="' + link + '" rel="external nofollow" rel="external nofollow" ]').addClass("active")
            // console.log($(topSeg).children("h1").text())
          }
        })
      })()
    })
  </script>
</head>
<body>
  <div id="toc">
    <ul>

    </ul>
  </div>
  <div id="content">
    <a name="seg-1" class="seg-begin"><h1>第1章节</h1></a>
    <div class="seg-content"></div>
    <a name="seg-2" class="seg-begin"><h1>第2章节</h1></a>
    <div class="seg-content"></div>
    <a name="seg-3" class="seg-begin"><h1>第3章节</h1></a>
    <div class="seg-content"></div>
    <a name="seg-4" class="seg-begin"><h1>第4章节</h1></a>
    <div class="seg-content"></div>
  </div>
</body>
</html>

具体的使用可以参考下面的文章。

Javascript 相关文章推荐
JQuery 风格的HTML文本转义
Jul 01 Javascript
Javascript中匿名函数的多种调用方式总结
Dec 06 Javascript
jQuery弹出层插件Lightbox_me使用指南
Apr 21 Javascript
jQuery代码实现对话框右上角菜单带关闭×
May 03 Javascript
浅谈JavaScript异步编程
Jan 20 Javascript
原生js轮播(仿慕课网)
Feb 15 Javascript
JS中showModalDialog关闭子窗口刷新主窗口用法详解
Mar 25 Javascript
ES6新特性四:变量的解构赋值实例
Apr 21 Javascript
js将当前时间格式化为 年-月-日 时:分:秒的实现代码
Jan 20 Javascript
vue2.0基于vue-cli+element-ui制作树形treeTable
Apr 30 Javascript
JS控制GIF图片的停止与显示
Oct 24 Javascript
vuex存值与取值的实例
Nov 06 Javascript
vue滑动吸顶及锚点定位的示例代码
May 10 #Javascript
webpack+vue.js构建前端工程化的详细教程
May 10 #Javascript
JS实现单张或多张图片持续无缝滚动的示例代码
May 10 #Javascript
Layer UI表格列日期格式化及取消自动填充日期的实现方法
May 10 #Javascript
angula中使用iframe点击后不执行变更检测的问题
May 10 #Javascript
JavaScript 装逼指南(js另类写法)
May 10 #Javascript
js中!和!!的区别与用法
May 09 #Javascript
You might like
摩卡咖啡
2021/03/03 咖啡文化
用PHP进行MySQL删除记录操作代码
2008/06/07 PHP
PHP+ACCESS 文章管理程序代码
2010/06/21 PHP
PHP生成短网址的3种方法代码实例
2014/07/08 PHP
PHP利用MySQL保存session的实现思路及示例代码
2014/09/09 PHP
php中session定期自动清理的方法
2015/11/12 PHP
PHP中时间加减函数strtotime用法分析
2017/04/26 PHP
js判断是否为数组的函数: isArray()
2011/10/30 Javascript
js history对象简单实现返回和前进
2013/10/30 Javascript
jQuery实现防止提交按钮被双击的方法
2015/03/24 Javascript
JS+DIV+CSS实现仿表单下拉列表效果
2015/08/18 Javascript
js实现的简洁网页滑动tab菜单效果代码
2015/08/24 Javascript
Vue.js每天必学之内部响应式原理探究
2016/09/07 Javascript
详解react-router如何实现按需加载
2017/06/15 Javascript
基于js中this和event 的区别(详解)
2017/10/24 Javascript
[08:29]DOTA2每周TOP10 精彩击杀集锦vol.7
2014/06/25 DOTA
python文件和目录操作函数小结
2014/07/11 Python
使用Python中PDB模块中的命令来调试Python代码的教程
2015/03/30 Python
Python实现堆排序的方法详解
2016/05/03 Python
virtualenv实现多个版本Python共存
2017/08/21 Python
python 数据生成excel导出(xlwt,wlsxwrite)代码实例
2019/08/23 Python
如何卸载python插件
2020/07/08 Python
从零开始的TensorFlow+VScode开发环境搭建的步骤(图文)
2020/08/31 Python
python自动化测试三部曲之unittest框架的实现
2020/10/07 Python
Python并发爬虫常用实现方法解析
2020/11/19 Python
深入浅析css3 border-image边框图像详解
2015/11/24 HTML / CSS
HTML5拖放效果的实现代码
2016/11/17 HTML / CSS
斯凯奇美国官网:SKECHERS美国
2016/08/20 全球购物
Notino希腊:购买香水和美容产品
2019/07/25 全球购物
销售团队获奖感言
2014/08/14 职场文书
四风问题个人对照检查剖析材料
2014/09/27 职场文书
刑事和解协议书范本
2014/11/19 职场文书
2014年社区工会工作总结
2014/12/18 职场文书
绍兴鲁迅故居导游词
2015/02/09 职场文书
留学推荐信(中英文版)
2015/03/26 职场文书
springboot拦截器无法注入redisTemplate的解决方法
2021/06/27 Java/Android