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


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 相关文章推荐
如何在一个页面显示多个百度地图
Apr 07 Javascript
多选列表框动态添加,移动,删除,全选等操作的简单实例
Jan 13 Javascript
jquery 中的each()跳出循环的语句
May 23 Javascript
javascript实现的平方米、亩、公顷单位换算小程序
Aug 11 Javascript
JQuery判断checkbox是否选中及其它复选框操作方法合集
Jun 01 Javascript
Javascript之深入浅出prototype
Feb 06 Javascript
Vue自定义指令拖拽功能示例
Feb 17 Javascript
jQuery插件HighCharts绘制2D半圆环图效果示例【附demo源码下载】
Mar 09 Javascript
JavaScript 实现 Tab 点击切换实例代码
Mar 25 Javascript
JS自定义函数实现时间戳转换成date的方法示例
Aug 27 Javascript
浅谈vue,angular,react数据双向绑定原理分析
Nov 28 Javascript
微信小程序下拉刷新PullDownRefresh的使用方法
Nov 29 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
php minixml详解
2008/07/19 PHP
推荐25款php中非常有用的类库
2014/09/29 PHP
用php守护另一个php进程的例子
2015/02/13 PHP
js 优化次数过多的循环 考虑到性能问题
2011/03/05 Javascript
让人期待的2011年度最佳 jQuery 插件分享
2012/03/16 Javascript
Jquery显示、隐藏元素以及添加删除样式
2013/08/09 Javascript
JQuery拖动表头边框线调整表格列宽效果代码
2014/09/10 Javascript
JavaScript改变CSS样式的方法汇总
2015/05/07 Javascript
AngularJS 应用身份认证的技巧总结
2016/11/07 Javascript
jQuery图片轮播(二)利用构造函数和原型创建对象以实现继承
2016/12/06 Javascript
jQuery Pagination分页插件使用方法详解
2017/02/28 Javascript
JavaScript中最常见的三个面试题解析
2017/03/04 Javascript
微信小程序实现鼠标拖动效果示例
2017/12/01 Javascript
vue采用EventBus实现跨组件通信及注意事项小结
2018/06/14 Javascript
vue用Object.defineProperty手写一个简单的双向绑定的示例
2018/07/09 Javascript
vue中利用Promise封装jsonp并调取数据
2019/06/18 Javascript
vue 动态表单开发方法案例详解
2019/12/02 Javascript
Vue router安装及使用方法解析
2020/12/02 Vue.js
[46:47]2014 DOTA2国际邀请赛中国区预选赛5.21 LGD-CDEC VS NE
2014/05/22 DOTA
Python实现ping指定IP的示例
2018/06/04 Python
python如何删除文件中重复的字段
2019/07/16 Python
Python3网络爬虫开发实战之极验滑动验证码的识别
2019/08/02 Python
小结Python的反射机制
2020/09/28 Python
python cookie反爬处理的实现
2020/11/01 Python
新西兰领先的内衣店:Bendon Lingerie新西兰
2018/07/11 全球购物
this关键字的含义
2015/04/08 面试题
竞聘医务工作人员的自我评价分享
2013/11/04 职场文书
学习雷锋做美德少年寄语大全
2014/04/09 职场文书
物业总经理助理岗位职责
2014/06/29 职场文书
小学生学习保证书
2015/02/26 职场文书
活动经费申请报告
2015/05/15 职场文书
雷锋的故事观后感
2015/06/10 职场文书
工作态度怎么写
2015/06/25 职场文书
2015大学迎新晚会主持词
2015/07/16 职场文书
《小乌鸦爱妈妈》教学反思
2016/02/19 职场文书
Win11应用商店打开闪退怎么解决? win11应用商店打不开的多种解决办法
2022/04/05 数码科技