仅需引入一个 js 文件,即可得到 Markdown 目录、
选择的是 marked.js 库进行解析,配合 highlight.js 进行代码高亮。
在线浏览 ,效果实例,建议 PC 端,Chrome 最佳
一、用法直接引入 markdown-toc.js
即可。index.html
为使用示例。
window.location.hash
均平滑滚动(smooth)
Markdown CSS( zhangjikai/markdown-css
&& github-markdown-css
)
修改与整理:.markdown-body
目录样式:自行添加了 .markdown-toc
自适应:px, em, rem,lib-flexible,px2rem-loader
无标题情况
三、注意事项平滑滚动功能仅测试了
Chrome
建议使用 marked.js
库来解析 HTML
,示例中 getMarkdownHTML()
这个方法,你会获得 Markdown
的对应 HTML
,以及生成目录所需要的数据( {text, level, anchor}
)。
四、美化
marked.js
在生成目录的过程中的作用:获得目录数据。
在 zhangjikai/markdown-css
的基础上,结合 github-markdown-css
进行配置。
.markdown-body
,
目录样式:自行添加了 .markdown-toc
。
自适应:px, em, rem:lib-flexible和px2rem-loader
五、锚点唯一性
此部分查看源码后一举击破,库本身就提供了此功能。
之前自己确定锚点的唯一性是靠标题顺序(1,2,3...),但这次查看源码后,发现自己欠缺很多考虑,源码中调用 slugger.slug
有很多数据预处理,并提供了锚点唯一值。
因为之后要添加目录,于是新增了 toc.push({text, level, anchor})
,其中的 toc
是用于存放各级标题数据的:
renderer.heading = function (text, level, raw, slugger) { if (this.options.headerIds) { // 遵循 options,如果 headerIds = false,也没必要制作 toc 了 let anchor = this.options.headerPrefix + slugger.slug(raw) toc.push({text, level, anchor}) return `<h${level} id="#${anchor}">${text}</h${level}>` } // ignore IDs return `<h${level}>${text}</h${level}>` }; 六、TOC 思路
考虑的情况:标题并不是按顺序写的,也就是说,顺序是乱的:开局一个二级标题,接下来就是五级标题,三级标题这样。
对应数组toc.push({text, level, anchor}) 0: {text: "1 一级标题", level: 1} 1: {text: "1.1 二级标题", level: 2} 2: {text: "2 一级标题", level: 1} 3: {text: "2.1.1 三级标题", level: 3} 4: {text: "2.1.2 三级标题", level: 3} 生成的 HTML 结构
<ul> <li>1 一级标题 <ul> <li>1.1 二级标题</li> </ul> </li> <li>2 一级标题 <ul> <li> <ul> <li>2.1.1 三级标题</li> <li>2.1.2 三级标题</li> </ul> </li> </ul> </li> </ul> 规则
* [index].level==当前level:栈顶如果是</li>,则弹出栈;输入<li>+text;推</li>入栈;index++。
* [index].level>当前level:如果栈顶是</ul>,则输入<li><ul>,推</li>入栈,推</ul>入栈;如果栈顶不是</ul>,则输入<ul>,推</ul>入栈;level++。
* [index].level<当前level:弹出 [(当前level-匹配level) * 2+1] 个值出栈;level=[index].level。
* index 达到最大,栈内数据全弹出。
示例
最右一列为栈,第一行为栈底。
</ul>(10)
表示,在第10行的时候弹出了 </ul>
,弹出时,以由下至上的顺序,若此行为多个标签,则以由右至左的顺序弹出。
且其对应行数,表示其在第几个循环被推入栈。
第 7
行的 </li></ul>(10)
表示,在第 7
个循环,先推入 </li>
入栈,再推入 </ul>
入栈;在第 10
行(所有循环已结束,次数所有数据均匹配完成,要打上闭合标签)时,先弹出 </ul>
, 再弹出 </li>
。
行数 | index | [index].level | 当前level | bool | (10) | |
---|---|---|---|---|---|---|
1 | 0 | 1 | 1 | == | 1 一级标题 | 已匹配(4) |
2 | 1 | 2 | 1 | > | 已匹配(4) | |
3 | 1 | 2 | 2 | == | 1.1 二级标题 | 已匹配(4) |
4 | 2 | 1 | 2 | < | ||
5 | 2 | 1 | 1 | == | 2 一级标题 | (10) |
6 | 3 | 3 | 1 | > | (10) | |
7 | 3 | 3 | 2 | > | (10) | |
8 | 3 | 3 | 3 | == | 2.1.1 三级标题 | 已匹配(9) |
9 | 4 | 3 | 3 | == | 2.1.2 三级标题 | (10) |
- | - | - | 全弹出,从下至上,从右至左 |
详细请查看代码:markdown-toc_note.js
文件,里面含有大量注释。
版权声明:
1、该文章(资料)来源于互联网公开信息,我方只是对该内容做点评,所分享的下载地址为原作者公开地址。2、网站不提供资料下载,如需下载请到原作者页面进行下载。