前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Jekyll 文章侧边索引导航

Jekyll 文章侧边索引导航

作者头像
zhonger
发布2022-10-28 11:13:25
1.4K0
发布2022-10-28 11:13:25
举报
文章被收录于专栏:仲儿的专栏仲儿的专栏

代码语言:txt
复制
-  [Jekyll 生成目录的方案](https://lisz.me/#jekyll-%E7%94%9F%E6%88%90%E7%9B%AE%E5%BD%95%E7%9A%84%E6%96%B9%E6%A1%88) 
    - [第一种方案](https://lisz.me/#%E7%AC%AC%E4%B8%80%E7%A7%8D%E6%96%B9%E6%A1%88)
    - [第二种方案](https://lisz.me/#%E7%AC%AC%E4%BA%8C%E7%A7%8D%E6%96%B9%E6%A1%88)
    - [第三种方案](https://lisz.me/#%E7%AC%AC%E4%B8%89%E7%A7%8D%E6%96%B9%E6%A1%88)

前言

  Jekyll 与 Hexo 不同之处有很多,其中一处是在文章页面中不支持原生 TOC Markdown 语法来自动生成目录。而在 Hexo 中,即使主题不支持侧边悬浮的优化目录导航,也可以通过最简单的方式在文章的开始位置生成目录。虽然这种目录永远固定在文章开始的地方,但是总算是能够通过大小标题来给读者一个大概的思路。

Jekyll 生成目录的方案

  如参考资料 1 中所提到的,如果想要在 Jekyll 中实现文章目录,有三种不同的方案可供选择:

第一种方案

  利用完整的标签来生成静态目录,可以看到在本文的开头就是这样的一个实例。这种方法的好处是不需要修改什么复杂的模板或者添加什么样式,Github Pages 也默认支持这种方式。不好的地方是与标准的 Markdown 语法略有不同,而且每次都得在文章内容页面开头加上以下代码。如果你使用带有 markdownlint 插件的编辑器编辑文章时,可能会有一堆告警。当然,如果不想折腾的人,这种方法不失为一种最简单方便的解决方案。

代码语言:javascript
复制
* TOC
{:toc}
第二种方案

  利用第三方插件 jekyll-toc。这种方式在实现上比上一种要更加优雅一些,不需要自己修改或编写代码,只需要执行以下步骤即可。缺点在于 Github Pages 不支持这类自定义插件,你可能需要使用自定义的 workflow.yml 文件来指导 Github Action 来编译生成静态文件。如果不怎么了解 Github Action,恐怕这种方式部署在 Github Pages 上也不是很省心。

代码语言:javascript
复制
# gemfile

gem "jekyll-toc"

# 添加后需执行 bundle install 安装插件
代码语言:javascript
复制
# _config.yml

# 在全局配置文件中启用 jekyll-toc 插件
plugins: ["jekyll-toc"]

# 默认为所有文章启用 toc
defaults:
  - scope:
      path: ""
    values:
      toc: true
第三种方案

  采用新增 jekyll 模板的方式来支持自动生成目录。这种方式也可以直接运行在 Github Pages 下。主要的步骤是:

  • toc.html 文件下载到 _includes 目录下;
  • 在 _layouts 需要使用 toc 功能的页面模板的 content 前面加上 % include toc.html html=content %

实践

  从上述三种方案综合来看,第三种方案能够同时支持自动生成目录和 Github Pages,比较适合预期的需求。另外,采用模板的方式还有一个好处,可以在全局配置文件 _config.yml 中一键设置“开启”或“关闭”,配置上比较简单。但如果仅仅照搬上述的第三种方案,还是不能完全满足实际的需求。因为第三种方案的结果是自动生成目录的内容,并不涉及到具体的布局,也就是说只能放在某一个固定的位置。总结的来说,实际的目标起码需要满足以下两点:

  • 目标一:目录位于正文右侧(或左侧),且当内容滑动时目录位置固定不变。
  • 目标二:目录在宽屏时自动显示,在窄屏或移动端分辨率不足时自动隐藏。

布局

  从目标一来看,其实在大部分的静态博客主题中都是有这样的功能的(PS:可能 Jekyll 是个例外,原生只支持静态目录)。我们可以先来看两个例子 hexo-theme-evenmarkdownguide。前面的例子是 Hexo 主题,其中采用的是 js 控制 toc 的 div 层在 position: absoluteposition: fixed 之间变换:当页面初始时,处于 absolute 位置;当页面在向下滑动时,处于 fixed 位置。这种方式需要有 js 代码的介入,增加了运算的成本(虽然其实很小)和维护成本(占比更大)。后面的例子是采用了 Bootstrap 框架中的 toc js 插件,能够满足目标一,且能跟踪内容位置来切换显示的二级目录,相对来说功能更加强大。唯一的缺点是,拖着 Bootstrap 这个大拖油瓶,如果本身的主题是基于 Bootstrap 框架的,那么就非常合适了。

  这里我们想要实践的是在未使用 Bootstrap 框架的 Jekyll 主题中增加目标一的功能,因此这两个例子的做法都不是很合适。实际上,从需要维护的代码量来说,第一个例子的做法所需的 js 代码应该是算少的,但是不是存在完全不使用 js 代码也能实现这样的功能的方案呢?实际上是存在的。据我们所知,现在已有的页面布局的方法大致有三种:Table 布局Div 布局Flex 布局。Table 布局算是最原始的布局方式了,主要利用 Table 的横列来组织页面中的各个元素的位置,特点是容易上手且不易出问题。缺点也比较明显,不大符合语义化 HTML 的规范,即 HTML 标签只做与它含义相同的事情。Table 标签作为表格布局标签,应该专注于展示表格数据,而非为整个页面布局操心。于是,Div 布局开始流行起来。Div 层的概念和布局的含义完全吻合,也容易理解。Div 布局比较让人头疼的地方是,页面中有很多浮动元素出现时,可能会出现各种各样想象不到的问题,某些布局之后被迫要清除浮动。Flex 布局的出现为 Div 布局提出了改善,使得页面布局不再被浮动元素和 Div 层浮动时内容大小为零所困恼。

  由于想要目录内容块随着内容滑动而改变 position,我们可以采用 sticky 的 position 方案。这可能是 css 的一大进步,通过定义 sticky 的 position 可以让元素根据相邻元素的滑动而改变 position。其实,sticky 就等于 absolute 加上 fixed。只是这种等价只在某些条件成立时才能生效。我们可以通过参考资料 2~4 来了解更多详情。

目录生成

  目录生成这里直接采用的是上述的第三种方案。具体在 post 模板页使用 toc 模块的代码如最后所示。

自适应

  为了实现目标二,这里采用了最简单的 CSS 媒体查询,即在平常 PC 端宽屏时采用如下 common.sass 中的样式。显示目录时,正文内容宽度为 720 px,目录宽度为 280 px。同时为了将目录与正文拉大间距以及更好区分,这里增加了 margin-left (30 px)、border-left(2px)和 padding(10px)。总计为,720+280+30+10*2=1050 px(这里忽略了 2px 的边界)。不显示目录时,让正文占据所有宽度,并设置目录块为 display: none,即隐藏该元素。具体实现如最终代码 common.sass 和 layout.sass 所示。在没有 sass 编译环境下,此处的 sass 代码可以取出转换为 css 使用。

最终代码

代码语言:javascript
复制
<!-- post.html -->

{% if site.toc %}
  <div class="container">  
    <div class="contents">
      <article class="markdown-body">
        {{ page.content }}
      </article>
    </div>   
    <div class="table-of-contents">
      <h2>Contents</h2>
      {% include toc.html html=content %}
    </div>
  </div>
{% else %}
  <article class="markdown-body">
    {{ page.content }}
  </article>
{% endif %}
代码语言:javascript
复制
<!-- common.sass -->

.container {
    width: 1050px;
    margin: 0 auto;
    display: flex;
    flex-direction: row;
    .contents{
        width: 720px;
    }
    .table-of-contents{
        padding: 10px;
        border-left: 2px solid #efefef;
        width: 280px;
        position: -webkit-sticky;
        position: sticky;
        top: 80px;
        margin-bottom: 80px;
        height: fit-content;
        margin-left: 30px;
        h2 {
            font-family: fantasy;
            color: #e32e00;
        }
        ul{
            margin-left: 20px;
            list-style-type: revert;
            font-size: 14px;
            line-height: 24px;
            color: #005b81;
            a{
                color: #005b81;
                &:hover{
                    color: #e32e00;
                    text-decoration: underline;
                }
            }
        }
    }
}
代码语言:javascript
复制
<!-- layout.sass -->

@media screen and (max-width: 1050px) {
    .post-content {
        .container {
            width: 100%;
            .contents {
                width: 100%;
                float: none;
                margin: 0 auto;
            }
            .table-of-contents {
                display: none;
            }
        }
    }
}

参考资料

版权声明:如无特别声明,本文版权归 仲儿的自留地 所有,转载请注明本文链接。

(采用 CC BY-NC-SA 4.0 许可协议进行授权)

本文标题:《 Jekyll 文章侧边索引导航 》

本文链接:https://cloud.tencent.com/developer/article/2143034

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
    • Jekyll 生成目录的方案
      • 第一种方案
      • 第二种方案
      • 第三种方案
  • 实践
    • 布局
      • 目录生成
        • 自适应
          • 最终代码
          • 参考资料
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档