Skip to main content

Page 的自定义悬浮 TOC 组件

· 5 min read
Kyle
CTO of the Ph.D. Creative Station

通过自定义页面 (Customized Page),我们可以得到更加灵活的页面布局和功能。在这个自定义页面中,我们希望能够最大化的利用 页面空间,因此我们需要禁用默认的 Table of Contents (TOC) 组件,并使用一个自定义的悬浮 TOC 组件来提供导航功能。

跳转该页面以查看 CustomTOC 组件的使用效果。

关闭 Page 默认的 TOC
---
hide_table_of_contents: true
---

CustomTOC 组件详解

CustomTOC 是一个功能强大、高度可定制的悬浮目录 (Table of Contents) React 组件,专为在 Docusaurus 的 MDX 页面中提供极致的导航体验而设计。它通过悬浮、可拖拽、可缩放的窗口,取代了页面固有的目录,从而释放了宝贵的屏幕空间,同时提供了灵活、现代的交互方式。

✨ 核心功能

  • 悬浮与持久化:组件以悬浮窗口形式存在,其位置、尺寸和折叠状态会通过 localStorage 自动保存,刷新页面后依然保持原样。
  • 自由交互:支持鼠标拖拽移动、右下角拖拽缩放,窗口大小和位置随心所欲。
  • 智能折叠:可最小化为一枚精致的悬浮球,通过单击悬浮球、双击标题栏或点击最小化按钮均可控制展开与折叠。
  • 主题自适应:自动检测 Docusaurus 的 light/dark 主题并切换样式,始终与您的网站风格保持一致。
  • 毛玻璃质感:采用现代化的毛玻璃 (Glassmorphism) 设计,背景半透明,视觉效果优雅。
  • 高亮当前章节:随着页面滚动,组件能智能高亮当前正在阅读的章节,并平滑滚动列表以确保其可见。
  • 黄金比例:窗口在缩放时,最小宽高比遵循黄金比例(1:1.618),确保了视觉上的和谐与美感。
  • 键盘快捷键
    • Ctrl/Cmd + Shift + T:快速显示或隐藏组件。
    • Esc:在展开状态下快速折叠组件。

🚀 如何使用

在您的 MDX 页面中,首先需要导入该组件,然后定义目录项,最后在页面任意位置渲染它。

示例:在 MDX 页面中使用 CustomTOC
import CustomTOC from '@site/src/components/CustomTOC';

// 1. 定义你的目录结构
const tocItems = [
{ href: '#feature-1', label: '功能一:悬浮与持久化', level: 2 },
{ href: '#feature-2', label: '功能二:自由交互', level: 2 },
{ href: '#sub-feature-2-1', label: '拖拽移动', level: 3 },
{ href: '#sub-feature-2-2', label: '缩放窗口', level: 3 },
{ href: '#feature-3', label: '功能三:智能折叠', level: 2 },
];

// 2. 在页面中渲染组件
<CustomTOC items={tocItems} title="页面导航" />

// 3. 在正文中设置锚点
<div id="feature-1"></div>
### 功能一:悬浮与持久化
// ...内容...

<div id="feature-2"></div>
### 功能二:自由交互
// ...内容...

<div id="sub-feature-2-1"></div>
#### 拖拽移动
// ...内容...

⚙️ 配置参数 (Props)

以下是您可以传递给 CustomTOC 组件的属性,用以自定义其行为和外观。

属性 (Prop)类型必需默认值描述
itemsArray[]定义目录结构的对象数组。
titleString"导航"显示在组件标题栏的文本。
classNameString""为组件根元素添加一个自定义的 CSS 类。

items 数组结构

items 数组中的每个对象都代表一个目录条目,其结构如下:

键 (Key)类型必需描述
hrefString链接的目标锚点,必须以 # 开头,例如 "#my-section"
labelString显示在目录中的文本标签。
levelNumber标题的层级(如 h2, h3)。用于实现目录项的层级缩进,level: 2 对应二级标题,level: 3 对应三级标题,以此类推。

🎯 锚点设置技巧

为了确保点击目录项能 100% 精准跳转,推荐使用 <div> 元素配合 id 来创建锚点,并将其放置在对应标题的正上方。

<div id="my-anchor-id"></div>
## 这是一个标题

这里是段落内容...

这种方法比依赖 Docusaurus 自动生成的标题锚点更稳定、更可靠。