现在阅览文章的网页往往都带有一个目录,方便点击跳转。目录一般都是根据文档中的标题级别直接生成的。

现在我们也来模仿一个简单的,无非就是把<h1><h2>...的序列转化成树嘛

思路是这样,我们首先找到所有文章的所有标题并且标记上,然后开始从前往后遍历标题,如果如果遇到同一级的标题,那就直接添加这个标题到后面,如果遇到级别更低的标题(h2 遇到 h3),说明从h3开始都是我的子目录,我们递归进入h2的子目录,直到遇到下一个高级别的标题(递归中找到更高的h2),说明完整的子目录生成完成,可以返回了。每一个新的子目录<ul>都是原<li>的子目录。

// 函数的含义是,在第index个标题处生成目录树,该标题级别为hLevel
function genFromTitle(hLevel, index){
let ele = ''
while (index < $('.isTitle').length) {
let t = $('.isTitle').eq(index)
if (t.attr('hLevel') > hLevel) {
// 遇到更小的标题,递归生成
let nt = genFromTitle(t.attr('hLevel'), index)
ele += `<li>${nt.ele}</li>`
// 从nt.index到index-1的标题都处理完毕,更新index
index = nt.index
}
else if (t.attr('hLevel') < hLevel) break // 遇到更大的标题,向上返回
else {
// 相同等级平行关系,直接添加标题项,下一个
ele += `<li>
<a> ${ t.text() } </a>
</li>`;
index ++;
}
}
ele = `<ul>${ele}</ul>`
return {ele, index} //index 也要返回去,父函数继续往后生成
} // elEssay为文档挂载点,elContent为生成的目录挂载点
function makeEssayContent(elEssay, elContent) {
// 首先标记所有标题
for (let i = 1; i <= 6; i++) {
elEssay.find('h'+i).addClass('isTitle').attr('hLevel', i)
}
elContent.html(genFromTitle(1, 0).ele);//从第一个一级标题开始生成
}

对于下面的标题,可以生成正确结果:

数据结构复习

一、线性结构

1.栈和队列

2.链表

二、树形结构

1.二叉排序树

三、排序

<ul>
<li><a> 数据结构复习 </a></li>
<li>
<ul>
<li><a> 一、线性结构</a></li>
<li>
<ul>
<li><a> 1.栈和队列 </a></li>
<li><a> 2.链表</a></li>
</ul>
</li>
<li><a> 二、树形结构 </a></li>
<li>
<ul>
<li><a> 1.二叉排序树 </a></li>
</ul>
</li>
<li><a> 三、排序 </a></li>
</ul>
</li>
</ul>

添加跳转功能

不能跳转的目录是没有什么用的,我们知道网页可以通过锚点直接跳转到对应的id,所以只要给每个标题添加一个id,再给对应的目录项设置跳转点就可以了

else {
t.attr('id', 'tp'+index) // 恰好每个标题有唯一index 直接拿来用
ele += `<li>
<a href="#tp${index}"> ${ t.text() } </a>
</li>`;
index ++;
}

添加折叠功能

根据上面的图,每个ul外面的li的上一个元素就是这个ul的父元素,所以可以在这个父元素设置标记,点击时将ul折叠即可。

//econtent是我的外包裹元素,这里选中所有符合条件的父元素(能展开和收缩的)
$('.econtent li ul').parent().prev().before($('<span class="foldable">&gt;</span>')) //添加一个标记
$('.foldable').on("click", (this)=>{
$(this).next().next().slideToggle()
$(this).toggleClass('collapsed')
})

标记有各种方法,我直接使用了一个大于号,在点击的时候旋转一下,就有生动的效果:

.foldable{
display: inline;
float: left;
margin-left: -1rem; /* 左移一个字符,与没有子项的同级标题对齐 */
transition: all .2s;
}
.collapsed{
transform: rotate(90deg);
transform-origin: center;
}

最终效果:见左侧

为Markdown/HTML文档生成一个简易目录的更多相关文章

  1. php markdown 接口文档生成工具 SummerDoc

    2017年9月18日 19:20:22 星期一 因工作需要, 用PHP写了一个管理接口文档的小工具, 下边介绍一下: 浏览器展示的效果: 项目地址:(码云) 例子(http://doc.hearu.t ...

  2. Markdown 文档生成工具

    之前用了很多Markdown 文档生成工具,发现有几个挺好用的,现在整理出来,方便大家快速学习. loppo: 非常简单的静态站点生成器 idoc:简单的文档生成工具 gitbook:大名鼎鼎的文档协 ...

  3. 安装doxygen(一个自动文档生成工具)+Graphviz图形可视化软件

    参考文章: http://www.fmddlmyy.cn/text21.html http://www.cnblogs.com/duguguiyu/archive/2008/06/29/1231852 ...

  4. 微软开源全新的文档生成工具DocFX

    微软放弃Sandcastle有些年头了,微软最近开源了全新的文档生成工具DocFX,目前支持C#和VB,类似JSDoc或Sphinx,可以从源代码中提取注释生成文档之外,而且还有语法支持你加入其他的文 ...

  5. MarkDown/reST 文档发布流水线

    相信很多朋友都在使用Markdown或者restructuredText格式来编写一些技术文档,也会把这些文档放在github上分享给社区.GitHub提供了很好的Markdown格式解析支持,但是这 ...

  6. 【转载】Java Restful API 文档生成工具 smart-doc

    谁说生成api文档就必须要定义注解? 谁说生成接口请求和返回示例必须要在线? 用代码去探路,不断尝试更多文档交付的可能性. 如果代码有生命,为什么不换种方式和它对话! 一.背景 没有背景.就自己做自己 ...

  7. Objective-C规范注释心得——同时兼容appledoc(docset、html)与doxygen(html、pdf)的文档生成

    作者:zyl910 手工写文档是一件苦差事,幸好现在有从源码中抽取注释生成文档的专用工具.对于Objective-C来说,目前最好用的工具是appledoc和doxygen.可是这两种工具对于注释的要 ...

  8. 小胖求学系列之-文档生成利器(下)-smart-doc

    叮叮叮....一阵铃声响起,大家都陆续来到了课堂,看老师没来,小张和小胖又闲聊起来,小张问:怎么样,smart-doc好用吧.小胖笑着说:挺好用的,不过? 小张看卖关子,问到:不过什么,有什么新发现? ...

  9. 如何使用Markdown 编写文档

    Markdown 是一种轻量级标记语言,用来编写文本文档,一般后缀名为.md.该语言在 2004 由约翰·格鲁伯(John Gruber)创建. 由于Markdown 语法简单,易读易写,变得越来越通 ...

  10. 入坑 docsify,一款神奇的文档生成利器!

    layout: postcategory: javatitle: 入坑 docsify,一款神奇的文档生成利器!tagline: by 沉默王二tags: - java Guide 哥是我认识的一个非 ...

随机推荐

  1. 【转载】 vscode如何在最新版本中配置c/c++语言环境中的launch.json和tasks.json?

    作者:来知晓链接:https://www.zhihu.com/question/336266287/answer/2144611720来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载 ...

  2. java中线程的6中状态

    1.背景 编写多线程相关的程序,必然会用到线程状态的相关知识点, 那么这篇博客就给大家系统的分析一下多线程的状态, 由于java中线程状态与操作系统中的线程状态划分有区别, 因此这里优先介绍操作系统的 ...

  3. Camera | 8.让rk3568支持前后置摄像头

    一.目标 本文主要目标是,支持前置摄像头0v5648.后置摄像头ov13850,以及移植过程遇到的一些小问题的解决. 1. 摄像头连接图 参考上图,摄像头详细信息如下: 2个摄像头均连接在I2C通道4 ...

  4. Axure 0基础实战入门 模拟一个app页面

    Axure 0基础实战入门 模拟一个app页面 第一次接触axure9,尝试模拟一个app页面与交互 页面原型 我选择了一个免费的日程app,下载rp文件后导入到axure 模拟实现登录页面 新建两个 ...

  5. Linux | Ubuntu 16.04.4 通过docker安装单机FastDFS

    Ubuntu 16.04.4 通过docker安装单机fastdfs 前言 很久没有写技术播客了,这是一件很不应该的事情,做完了事情应该有沉淀的. 我先说一点前情提要,公司的fastdfs突然就挂了, ...

  6. c++学习笔记(五):文件操作

    目录 文件操作 文本文件 写文件 include 读文件 include 二进制文件 写文件 读文件 文件操作 程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放 通过文件可以将数据持久化 ...

  7. 为什么Java已经不推荐使用Stack了?

    为什么不推荐使用Stack Java已不推荐使用Stack,而是推荐使用更高效的ArrayDeque 为什么不推荐使用 性能低:是因为 Stack 继承自 Vector, 而 Vector 在每个方法 ...

  8. [Tkey] 生日礼物

    题意简述 彩珠有 \(n\) 个 \(k\) 种,每个珠子都有一个坐标 \(p_{i}\),求最小的区间长度,使得这个区间包含全部的 \(k\) 种彩珠. 分析 发现我们可以维护每一种颜色的最近出现坐 ...

  9. 分布式执行引擎Ray-部署

    1. Ray集群 Ray 有多种部署模式,包括单机,k8s,VM等. 在单机下,可以直接用ray.init来快速启动ray的运行环境,但是如果要在多节点上执行,则必须先部署Ray Cluster. 一 ...

  10. c++中字符/串->整数

    char字符->整数数字:std::isdigit 用于判断某个字符是否为数字(0-9). 字符串->数字:std::stoi 用于将字符转换为整数. int isdigit( int c ...