📢 新文章推送 · 每周更新优质内容 · 订阅更新 →
向下滚动
测试笔记

文章标题锚点链接功能实现

AI 智能总结

功能需求

长文章中读者经常需要引用或分享某个具体章节。传统做法是手动查找标题的 id 再拼接 URL,效率很低。为每个标题自动添加锚点链接按钮,可以一键获取指向该章节的完整 URL。

核心实现

创建一个独立的 head-anchor.js 模块,负责动态注入锚点按钮:

 1class HeadingAnchor {
 2  constructor() {
 3    this.headings = document.querySelectorAll(
 4      '.post-content h2, .post-content h3, .post-content h4'
 5    );
 6    this.init();
 7  }
 8
 9  init() {
10    this.headings.forEach(heading => {
11      const anchor = document.createElement('a');
12      anchor.className = 'heading-anchor';
13      anchor.innerHTML = '#';
14      anchor.href = `#${heading.id}`;
15      anchor.title = '复制链接';
16
17      anchor.addEventListener('click', (e) => {
18        e.preventDefault();
19        const url = `${location.origin}${location.pathname}#${heading.id}`;
20        navigator.clipboard.writeText(url).then(() => {
21          anchor.innerHTML = '✓';
22          anchor.classList.add('copied');
23          setTimeout(() => {
24            anchor.innerHTML = '#';
25            anchor.classList.remove('copied');
26          }, 1500);
27        });
28      });
29
30      heading.appendChild(anchor);
31    });
32  }
33}
34
35export default HeadingAnchor;

关键设计点

DOM 动态注入

不使用 Hugo 模板在编译期生成锚点 HTML,而是通过 JS 在客户端动态注入。这样做的优势是:

  • 保持 Markdown 源文件的简洁性
  • Hugo 的 Markdownify 渲染出的标题在某些配置下可能不包含 id,JS 注入更可控
  • 方便与 SWUP 等页面切换库配合

剪贴板 API

使用 navigator.clipboard.writeText() 将完整 URL 写入剪贴板。相比传统的 document.execCommand('copy'),Clipboard API 是异步的、基于 Promise,且支持更精细的权限控制。

复制成功后锚点文字从 # 变为 并添加 .copied 类,1.5 秒后恢复,提供清晰的操作反馈。

SWUP 兼容

SWUP 进行页面切换时 DOM 会被替换,需要在 SWUP 的内容替换事件中重新初始化:

1import HeadingAnchor from './head-anchor.js';
2
3document.addEventListener('swup:contentReplaced', () => {
4  new HeadingAnchor();
5});
6
7document.addEventListener('DOMContentLoaded', () => {
8  new HeadingAnchor();
9});

CSS 样式

锚点按钮默认隐藏,hover 标题时淡入显示:

 1.heading-anchor {
 2  display: inline-block;
 3  margin-left: 8px;
 4  font-size: 0.85em;
 5  color: var(--color-primary);
 6  opacity: 0;
 7  transition: opacity 0.2s ease;
 8  text-decoration: none;
 9}
10
11h2:hover .heading-anchor,
12h3:hover .heading-anchor,
13h4:hover .heading-anchor {
14  opacity: 0.7;
15}
16
17.heading-anchor:hover {
18  opacity: 1 !important;
19}
20
21.heading-anchor.copied {
22  opacity: 1;
23  color: #22c55e;
24}

这样在不打扰正常阅读的前提下,需要时锚点自然浮现,交互完成后给予绿色✓的确认信号,整个流程简洁且优雅。

专题系列 Lumin Blog 优化
17 / 22
版权声明

本文作者 Lumin

本文链接 https://www.zhengquan.xyz/biji/heading-anchor-links/

许可协议 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!

请作者喝杯咖啡 ☕

  • 微信打赏
    微信支付
  • 支付宝打赏
    支付宝
点击按钮查看打赏二维码
🎁 推荐工具
试试这些实用在线工具,提升工作效率
前往工具集 →

留言评论

期待你的想法

评论加载中