为Hugo主题添加动态跟随目录Scrollspy效果

本文介绍了如何在自建博客中使用Hugo的TableOfContents功能生成目录,并结合GumshoeJavaScript实现动态跟随效果,同时处理了BootstrapScrollspy在异步加载元素影响下的问题。
摘要由CSDN通过智能技术生成

自己搭建设计博客主题时候,采用了主栏与侧边栏的双栏设计,在博客文章页面,侧边栏可以用来呈现文章的目录(一级标题,二级标题等),方便读者了解文章整体结构脉络,也方便读者进行跳转操作。基础的目录html部分可以通过Hugo原生的{{ .TableOfContents }}函数实现。除了基本的目录,自己还想为目录部分添加上动态跟随的工作,即,目录会高亮出目前读者所浏览部分的标题。博客原先采用的bootsrap框架自带的Scrollspy模块可以实现这个功能,但是如果页面元素发生高度变化(例如,评论功能的异步载入),该Scrollspy功能会出现位置定位不准的问题。经过一番尝试后,自己最后使用了gumshoe作为替代实现动态跟随目录的效果,本文记录整个相关实现的细节。

目录样式

实现方案

目录html的生成

通过Hugo原生的{{ .TableOfContents }}函数实现,将下面的代码放入你想将目录放入的部分。

<!-- Put this Hugo function where you want to locate TOC -->
<div class="toc-div">
{{ .TableOfContents }}
</div>

Gumshoe javascript的插入

添加Gumshoe javascript部分,注意需要将该部分放在整个body末尾。

<script src="<https://cdn.jsdelivr.net/npm/gumshoejs@5.1.2/dist/gumshoe.min.js>"></script>
<script>
	var spy = new Gumshoe('#TableOfContents a', {
	    nested: true,
	    nestedClass: 'active'
    });
</script>

CSS文件的

下面是本站目录部分所采用的CSS样式,可以作为参考。

我用一个流程图描述一下整个{{ .TableOfContents }}所生成的html标签的结构

其中高亮所突出部分的样式可在.active class下进行相关修改

本站大部分文章正文只会采用两个级别的标题,Hugo默认也只会生成两个级别的目录,如有多级标题的需求,对应修改即可。

/* Both levels of nav */
#TableOfContents li, #TableOfContents ul{
  list-style-type: none;
}

#TableOfContents ul{
  padding-left: 0px;
}

#TableOfContents li > a {
  display: block;
  padding: 4px 20px;
  font-size: 90%;
  color: #919eB1;
}

#TableOfContents li > a:hover,
#TableOfContents li > a:focus {
  padding-left: 19px;
  color: #3A6bA5;
  text-decoration: none;
  background-color: transparent;
  border-left: 1px solid #3A6bA5;
}

#TableOfContents li.active > a,
#TableOfContents li.active > a:hover,
#TableOfContents li.active > a:focus {
  padding-left: 18px;
  font-weight: bold;
  color: #3A6bA5;
  background-color: transparent;
  border-left: 2px solid #3A6bA5;
}

/* Second level */
#TableOfContents li > ul {
  padding-bottom: 10px;
}

#TableOfContents li li > a {
  padding-top: 1px;
  padding-bottom: 1px;
  padding-left: 30px;
  font-size: 12px;
  font-weight: normal;
}

#TableOfContents li li > a:hover,
#TableOfContents li li > a:focus {
  padding-left: 29px;
}

#TableOfContents li li.active > a,
#TableOfContents li li.active > a:hover,
#TableOfContents li li.active > a:focus {
  padding-left: 28px;
  font-weight: 500;
}

#TableOfContents .nav-link.active + ul {
  display: block;
}

为目录部分加上stick置顶

目录部分与正文部分不同,不应该随页面上下滑动,需要固定显示,一个实现方法是将目录设置stick的position样式,可以参考下面的css方案。

.toc-div {
    position: -webkit-sticky; /* safari 浏览器 */
    position: sticky; /* 其他浏览器 */
    top: 20px;
}

折叠隐藏二级标题

如果文章中的标题过多,目录会显得比较臃肿,一个解决方法是,隐藏二级标题,只有浏览部分所在一级标题下的二级标题才展开显示。实现这样的功能也非常简单,只需多添加这样几行样式到css文件中即可。

左图:目录加上二级目录折叠,右图:目录未加上二级目录折叠

#TableOfContents li > ul {
    display: none;
}

#TableOfContents li.active > ul {
    display: inherit;
}

原理

整个动态跟随目录实现的原理非常简单:gumshoe会根据浏览器所在的位置,推算出当前位置在哪个标题下,并将目录部分标题对应的<li>标签加上.active类,我们在css文件中为.active类写上不一样的样式就能实现整个动态跟随高亮的效果。

  • 23
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值