功能介绍
本文记录了对 Quartz 预览气泡(Popover)进行的深度定制。通过将原生 Popover 重构为自定义组件 Custom.Popover,我们解决了预览窗口相互干扰的问题,并显著提升了锚点定位的准确性:
- 独立实例机制:解决了“同一个文档中多次引用同一篇文章时,预览窗口相互干扰”的问题。通过为每个链接(Pathname + Hash + ID)生成唯一标识,确保每个预览窗口拥有独立的状态和滚动位置。
- 鲁棒滚动定位:参考 Todo 插件的实现,引入了多次尝试滚动机制(使用
setTimeout阶梯尝试)。有效解决了内容加载缓慢或动态渲染导致锚点定位失效的问题。 - 全站预览统一:不仅增强了正文中的维基链接(Wikilinks)预览,还同时优化了反向链接(Backlinks)和待办事项(Todo)的预览体验。
优化逻辑
独立 ID 生成
在原生的实现中,预览窗口仅基于路径识别(popover-${link.pathname})。当一个页面中有多个链接指向同一篇文章的不同段落时,它们会共用同一个预览窗口。
自定义版本将其修改为:
const popoverId = `popover-${link.pathname}${hash}${link.id ? "-" + link.id : ""}`这确保了即使是同一个页面,只要锚点不同或是不同位置的引用,都能获得专属的预览视图。
阶梯式重试滚动
为了应对 Quartz 动态内容加载带来的异步问题,我们不再只在展示瞬间滚动一次,而是进行多次重试:
const scrollPopover = () => {
// ... 执行滚动定位
}
scrollPopover()
setTimeout(scrollPopover, 50)
setTimeout(scrollPopover, 100)如何使用
下载文件
请将以下文件保存至项目的 quartz/custom/ 对应位置:
启用插件
1. 修改全局配置 (quartz.config.ts)
禁用原生的预览功能:
// quartz.config.ts
configuration: {
// ...
enablePopovers: false, // 禁用默认预览气泡,使用 custom/Popover
}2. 配置布局组件 (quartz.layout.ts)
在 afterBody 中注册自定义组件:
// quartz.layout.ts
import * as Custom from "./quartz/custom"
export const sharedPageComponents: SharedLayout = {
// ...
afterBody: [
Custom.ImageZoom(),
Custom.Popover(), // 启用增强版预览插件
// ...
],
}