headings
headings 是 Astro 的 post 提供的一个非常方便的 prop
结构处理
如果我的Markdown文件是如下结构
得到的headings是一个扁平化的数组
然而一般toc的结构都是<ol>
> <li>
> <ol>
,将headings聚合成树形会比较好实现
构建树形的headings
通常情况下三级目录就已经足够了,所以我这里并没有用递归,只是简单处理了下
然后就得到了
渲染组件
这里采用了递归缩减行数 :p 如果用astro写三层ol缩进将会看着极其恶心
这样,我们就得到了一坨三级toc目录~
让TOC变得丝滑!
上面实现的目录定位十分生硬,没有那种响应式的丝滑感觉 :(
还得让它变得高级起来!
实现下面的效果时,先准备好一个对应关系的列表
这个列表的每个对象的 link
= <a>
, target
= <h1><h2>...
,
平滑定位
很简单,阻止 <a>
标签冒泡,通过window.scrollTo(smooth)
定位到<h1>
目标就好了
目录同步
最开始我是使用window.addEventListener("scroll")
去实现的,但是通过监听滚动事件,开销会比较大,而且同步并不是很丝滑,最终找到了IntersectionObserver
的方案,开销比监听滚动事件小很多,稍微修改了一下,效果十分的amazing!无敌!
稍微加个样式
最终效果就是这个博客的toc了,纵享丝滑~