静态博客目录生成方案选择

简约不简单

March 18, 2020 · 13 mins read

文章有目录才方便阅读,我想要的效果是目录悬浮在右侧并且高亮当前的导航目录,这样的目录才算有用。

看着挺简单但其实需要考虑的因素不少,下面分两个部分评估一下。前半部考虑如何生成目录,后半部考虑如何应用JavaScript自动高亮。

生成目录

我们先考虑下如何生成目录。

Markdown内建目录

* toc
{:toc}

Markdown语法生成的TOC元素和结构是<ul id="markdown-toc"><li><a id="markdown-toc-xxx">,这就有几个问题:

  1. 静态网站比如Jekyll,只有文章的正文是Markdown格式,其他公用部分是放在Layouts的,那么:
    • 每一个.md文件都需要加这一行,尽管很少
    • TOC只能放在正文里并且位置固定,这样的目录意义不大。如果能放在正文两侧并且是position:sticky的效果还可以接受。尝试了下,没有成功:sweat_smile:
    • 后期维护困难,如果想调整每一个.md文件都要修改:scream:
  2. 无法指定CSS class,应用CSS就要困难些。

如果标题包含多语言,有个情况是目录里的链接会被URI编码,这就会造成一些的JS库无法工作。这个事情要各打五十大板,为什么这么说呢?

Markdown编码干啥捏(可能是遵循标准)?就直接多语言字符输出,我们点链接的时候人浏览器知道编码!

JS库没考虑周全吧,jQuery("#markdown%E5%86%85...")人jQuery要报错啊!用属性选择器就没问题jQuery("[id='markdown%E5%86%85...']")

出局!

Jekyll Pure Liquid TOC

官网 :arrow_upper_right::静态目录生成方案,也就是说目录随着文章内容一起生成静态文件。

Liquid是一种模板语言,Jekyll用它来处理模板,和Velocity、FreeMarker差不多。Jekyll的默认Markdown渲染器是kramdown :arrow_upper_right:,它是标准Markdown的扩展集,也就是说兼容Markdown并且提供更加丰富的语法来锦上添花。

嘿~真是不错,标准语法不影响书写流畅度,额外语法解决一些棘手问题,确实就很顺手了:yum:

这个方案的思路是用Liquid抓取Header来生成Markdown无序列表,然后通过kramdown指定元素CSS。

提供很多配置参数,高度可定制。支持设置<ul><li><a>三个元素的CSS class,但kramdown只能应用class到顶级<ul>,和其他JavaScript库合作的话就会有一些问题。

生成的kramdown目录就像这样:

- {:.your-li-class} [Header](#header){:.your-a-class}

Jekyll Table of Contents

官网 :arrow_upper_right::纯JS目录生成器,这是动态生成方案,也就是说当浏览器打开文章的时候目录才动态生成。

除了生成目录,它还可以给每个Header加上<i>标签,点击后滚动到顶部,我感觉没什么用处,有个配置noBackToTopLinks可以关闭该功能。

既然是JavaScript就能加些渲染效果,比如目录淡入等,看起来还不错。

还有两个配置特别有用,一个是可以设置<ul>/<ol><li>的CSS class,方便和其他JavaScript库配合使用,但暂时不支持设置<a>的CSS class。

另一个是headers,可以控制哪些Header出现在TOC里,它其实是jQuery Selector,发挥想象吧:smirk:

TOC Markdown Generator

官网 :arrow_upper_right::这个是在正文的前面插入目录,而且只能抓取<h1><h2><h2><h3>来生成目录。

功能有限,限制颇多,出局!

自动高亮

这个效果只有依靠JavaScript来实现。

jQuery One Page Nav

这个插件只管应用JS效果,你得自己准备目录内容。主要功能包括:

  • 点击导航条目的时候平滑滚动
  • 浏览的时候自动高亮当前导航条目

由于上面提到的原因,如果目录包含多语言,功能将失效。可以通过指定Header的id属性来解决,kramdown提供语法支持。

Bootstrap Scrollspy

官网 :arrow_upper_right::Bootstrap现成组件,提供JS和CSS,开箱即用。

只提供自动高亮当前导航目录的功能,有个亮点是如果子目录高亮,父目录也会同时高亮。但如果有三级目录,浏览到第三级的时候,高亮的目录会连成一片,就有点儿喧宾夺主的感觉了。

同样的,还是自己准备目录内容。一样无法高亮多语言目录,解决方法同上。

方案选择

现在总共有四种组合供我们选择。

Pure Liquid TOC方案如果不需要高亮效果,用它来生成目录还是不错的。但由于受kramdown的限制,使用起来还是不方便。

Jekyll Table of Contents + One Page Nav:配合完美,基本上只需要调整下CSS就能工作了。

Jekyll Table of Contents + Scrollspy:由于Scrollspy需要指定<a>的class,提交了一个Pull Request :arrow_upper_right:(更新:已经被merge到了原项目)到Jekyll Table of Contents来支持这个配置。

还有个Pull Request :arrow_upper_right:你可能也需要,给Tag Cloud :arrow_upper_right:加了个配置background: true | false,这样就可以选择应用颜色深浅到文字还是背景色,效果在这里Tags

选择合你口味的吧:heart_eyes:

搭建博客姊妹篇

Cloudflare配置考量
静态博客评论系统的比较及选择

:clock9:上次更新: 2020-10-18