一篇很长的文章:测试目录组件
测试6,800 字
- #TOC
- #React Bits
- #长文
引言
这是一篇为了测试文章页 TOC 目录组件而准备的长文章。它包含足够多的章节和子章节,用来验证目录是否可以随窗口范围自动调整显示范围、是否可以高亮当前阅读位置,以及是否可以顺畅地点击跳转。
在开始之前,建议先把窗口宽度调整到 1440px 以上,这样左侧目录会正常显示。然后从上到下慢慢滚动,观察目录中的高亮项是否跟随文章内容移动。
为什么需要目录
长文章最大的问题不是内容太多,而是读者容易迷路。目录的作用是给读者一张地图,让人随时知道:我现在在哪里,接下来还有什么。
一个好的目录应该满足三个条件:
- 始终可见,不随正文滚动而消失
- 能够反映当前阅读位置
- 点击后可以平滑跳转到对应章节
本站使用 React Bits 的 Animated List 组件作为目录载体,配合 IntersectionObserver 实现滚动高亮。
目录组件的实现
目录组件主要由两部分组成:Animated List 负责列表的入场动画和交互,外层脚本负责监听滚动并更新当前章节。
滚动监听
实现方式是在文章页挂载一个 IntersectionObserver,观察所有带 id 的标题元素。当某个标题进入视口中间区域时,就把它对应的目录项设为激活状态。
const observer = new IntersectionObserver(entries => {
const visible = entries
.filter(entry => entry.isIntersecting)
.sort((a, b) => a.boundingClientRect.top - b.boundingClientRect.top);
if (visible.length > 0) {
const index = headings.findIndex(h => h.id === visible[0].target.id);
if (index >= 0) setActiveIndex(index);
}
}, { rootMargin: '-20% 0px -65% 0px' });
高亮当前章节
Animated List 原本通过鼠标悬停或键盘选择来高亮条目。我们给它增加了一个受控的 activeIndex 属性,当滚动监听发现当前章节变化时,外部直接把新的索引传进去。
这样既保留了 React Bits 的入场动画,又让目录拥有了滚动同步能力。
视口范围调整
当窗口高度较小时,目录列表会限制最大高度并出现内部滚动。当窗口高度较大时,目录会使用更多空间,减少滚动的频率。
这个行为由 CSS 的 max-height 和 overflow 控制,Animated List 组件本身支持显示或隐藏滚动条。
长文排版
长文排版的目标是降低阅读负担。行宽、行高、字号、段落间距,每一个细节都会影响阅读体验。
标题层级
文章使用两级标题:h2 作为主要章节,h3 作为章节内的小节。目录中同样保留两级结构,方便读者快速定位。
标题的层级不应该超过三级。超过三级之后,目录会变得像一本书的目录,而不是一篇文章的目录。
段落节奏
长文的段落不宜过长。一个段落只表达一个核心意思,读完一段就能停下来喘口气。
适当使用列表、引用和代码块,可以让页面产生节奏变化,避免大段文字造成的视觉疲劳。
好的长文不是把内容写长,而是把每一个部分都写得值得读。
测试场景
你可以通过以下几种方式测试目录:
- 从顶部快速滚动到底部,观察目录高亮是否连续变化。
- 点击目录中的任意条目,确认页面平滑滚动到对应标题。
- 把窗口高度调小,确认目录出现内部滚动条。
- 使用键盘 Tab 和 Enter 操作目录,确认可访问性。
- 返回首页再进入本文章,确认目录仍然正常工作。
性能与体验
目录的滚动监听使用 IntersectionObserver,而不是在 scroll 事件里做大量计算,因此性能开销很小。
Animated List 的入场动画只在元素进入视口时触发一次,不会在滚动过程中反复重排。
对于更长的文章,建议把目录的最大高度设置为视口高度的一定比例,而不是固定像素,这样在不同屏幕上都有一致的体验。
结语
这篇长文章到此结束。如果你能看到左侧目录完整工作,说明 TOC 组件已经通过了基础测试。
接下来可以继续补充更多真实文章,或者根据测试结果调整目录的样式与交互细节。