Skip to content

fix(docs): 统一哈希锚点系统——目录点击加粗、内容锚点跳转、滚动同步哈希 - #316

Merged
vshengbro merged 1 commit into
masterfrom
feat/docs-hash-anchor-system
Oct 17, 2026
Merged

vshengbro merged 1 commit into
masterfrom
feat/docs-hash-anchor-system

Conversation

@vshengbro

Copy link
Copy Markdown
Collaborator

缺陷与根因

  1. 目录点击后不加粗:spy 把 fragment_target 返回的完整 href 当锚点 slug 再匹配,永不相等 → URL 带 fragment 时高亮永久冻结
  2. 内容锚点链接不生效:markdown 写 #run_function,标题 id 是 slugify 后的 run-function → 查找落空退回滚到顶部
  3. 滚动不更新哈希:两套系统互不感知

方案(hash 单一事实源,replaceState 结构性防循环)

  • 点击/前进后退/粘贴 → hashchange → route_signal(含锚点)→ 滚动到锚点;fragment 在「hash 变化且滚动未动」窗口期优先决定高亮(点击意图即时反馈)
  • 滚动 → 100ms 轮询几何 → 更新 TOC 激活 + history.replaceState 写 hash(不触发 hashchange、不进历史栈)
  • 滚动永不 set_hash,hashchange 路径永不写 hash —— 两方向无交集,循环在结构上不可能
  • rewrite_link 对锚点过 slugify(对已有 slug 幂等、保留 CJK),内容作者的函数名锚点从此匹配标题 id
  • 附带:Router::navigate 早退改为含锚点全路由比较(原实现吞掉同页锚点导航)

实测(0.30.10,1440px)

目录点击 0.35s 内加粗+滚动;内容链接滚动 0→1279 且目录同步;滚动 0/1200/底部 hash 跟随稳定不闪烁;跨页锚点精确落位(标题-72px 滚动边距);后退恢复 hash+滚动+高亮;冷启动深链滚动+加粗;760px 移动端无 TOC 不报错。

版本 0.30.9 → 0.30.10。

三个缺陷的根因与修复:

1. 目录点击后不加粗: active_toc_entry 把 fragment_target 返回的完整
   href 当成锚点 slug 再匹配(Some(href) == Some(anchor) 永假)→ URL
   一旦带 fragment,spy 永远返回 None,高亮冻结。重构为状态化 spy:
   seen_hash/scroll_at_hash 记录最近一次外部 hash 变化,fragment 仅在
   「hash 变了但滚动还没动」的窗口期作为意图优先,滚动一动几何接管,
   点击项不再永久钉死高亮。

2. 内容超链接锚点不生效: markdown 作者写 #run_function(函数名带下划
   线),而标题 id 经 slugify 变成 run-function(下划线非 slug 安全字符)
   → getElementById 落空退回滚到顶部。rewrite_link 现在对锚点部分同样
   过 slugify(同页 #x 与跨页 ./a.md#x 两处),对已有 slug 幂等、保留
   CJK;语料库确认无 % 编码锚点与 raw HTML id 锚点,安全。

3. 滚动不更新哈希: spy 现在把几何结果用 history.replaceState 写进 URL
   —— 不触发 hashchange,所以滚动写哈希不会回灌锚点滚动(结构性防循
   环),也不污染历史栈。hashchange(点击/前进后退/粘贴)→ route_signal
   → 滚动+标记;滚动 → 几何 → 标记 + replaceState。两个方向永不相交。

附带修复(同特性域潜在 bug): Router::navigate 的早退比较改为含锚点的
全路由 —— 原来只比路径部分,会把 /page → /page#section 的同页锚点导
航整体吞掉。

实测(0.30.10 本地构建, 1440px 视口): 目录点击 0.35s 内加粗+滚动落位;
内容链接点击滚动 0→1279 且目录同步; 滚动 0/1200/底部 hash 跟随且稳定不
闪烁; 跨页锚点链接滚动到 581(标题-72px 滚动边距)精确落位; 后退恢复
hash+滚动+高亮; 冷启动深链滚动 1993+加粗; 760px 移动端无 TOC 不报错不
写 hash。

版本 0.30.9 → 0.30.10。
@ghfind-review ghfind-review Bot added the review: high ghfind author score; see https://ghfind.com label Oct 17, 2026
@vshengbro
vshengbro merged commit 1698628 into master Oct 17, 2026
8 checks passed
@vshengbro
vshengbro deleted the feat/docs-hash-anchor-system branch October 17, 2026 16:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review: high ghfind author score; see https://ghfind.com

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant