TL;DR

这次更新三件事:

  1. 划词高亮 + 读书笔记:选中正文就能用荧光笔高亮、随手记笔记,刷新不丢,数据只保存在本地浏览器
  2. 搜索升级 Pagefind:中文分词、模糊匹配、全文检索,搜中文终于能搜对了
  3. 修掉几个隐藏 bug:移动端菜单按钮点不动、双链预览大面积失效、装备图没有尺寸、构建明显变快

一、划词高亮与读书笔记:读文章也能做笔记

写博客的人大多也爱读书。以前读到一篇好文章,想把某句话”圈起来”、在旁边写两句,得复制到笔记软件里——来回切换很打断阅读。

现在不用了。在正文里选中一段文字,就会浮出一个工具条:

  • 三种颜色的荧光笔(黄 / 绿 / 蓝),点一下就把这段文字划亮
  • 也可以直接写一条「笔记」,跟着这段文字一起存下来

高亮和笔记会保存在本地浏览器(localStorage),刷新页面不会丢,下次再来这篇文章,之前划的线、写的批注都在。

右下角有一个「笔记」按钮,点开是当前文章的笔记面板:

  • 每一条笔记显示原文片段 + 你写的内容 + 时间
  • 点条目能跳回正文里对应的高亮位置
  • 可以随时删除

有个细节我特意做了提示:这些笔记只保存在你自己的浏览器里,不会上传到服务器。这也意味着——换浏览器、清缓存,笔记就没了。所以它更适合”临时记录”而非”长期归档”。真要认真做知识管理,还是得走我博客里聊过的那套(本地 Markdown + 同步)。

实现上是个独立的 Astro island 组件(ArticleHighlight),没有引入任何前端框架,纯原生 JS。踩了一个挺典型的坑:Astro 组件的 <style> 默认是作用域样式,只对模板里静态渲染的元素生效,而我用 JS 动态创建的高亮 <mark> 和笔记条目全都”裸奔”了——一度所有高亮都是浏览器默认的黄色。改成 <style is:global> 后(类名都带了 note- 前缀,不会污染全局),三色区分、卡片样式才真正生效。

二、搜索升级 Pagefind:中文搜索终于好用了

以前的站内搜索是自己写的前端逻辑:把文章索引成 JSON,用户输入后做子串匹配。凑合能用,但短板很明显:

  • 中文只能精确匹配,搜”链接”搜不到”双向链接”之外的变体,更别说错别字、同义词
  • 索引只取了正文前 1500 字,后面搜不到
  • 没有分词,搜索体验全看运气

这次换成了 Pagefind(我早前写过一篇搜索方案横评,结论就是它对 Astro 博客最合适,这次终于落地了)。它是构建期给静态站点生成索引,然后前端零框架调用。

带来的实际改善:

  • 中文分词:搜”双向链接”能命中相关文章,Pagefind 自动做中文分词
  • 全文检索:索引覆盖整篇文章,不只是开头
  • 带高亮片段:每条结果直接给出匹配上下文,关键词自动标亮
  • /search?q=关键词 直达:分享一个带搜索词的链接,对方打开就出结果

实现上有几个要点,记录一下:

  • 构建脚本末尾加一行 pagefind --site dist --force-language zh,生成 dist/pagefind/ 索引
  • 用 data-pagefind-ignore 让只有文章页进索引(首页、归档、分类等不进),避免搜出一堆导航页
  • 文章页用 data-pagefind-meta="category:xxx" 注入分类,前端可以做分类筛选
  • 热门标签改为构建期静态渲染(原来靠 JS 从索引里现算,多一次请求)

搜索页的 UI(分类筛选、搜索历史、键盘导航 ↑↓/Enter/Esc)都保留了,只是底层引擎换了。

三、顺手修掉的几个 bug

这轮改动范围大,顺手揪出并修掉了几个藏了很久的问题:

  • 移动端右上角菜单按钮点了没反应——根因很有意思:Sidebar.astro 里一行 if (overlay) onclick = closeDrawer; 少了 overlay. 前缀,结果把关闭函数赋给了 window.onclick。于是页面上任何一次点击都会立刻把刚打开的抽屉关掉——看起来就是”按钮无效”。改成 overlay.onclick 就好了。
  • 双链预览大面积失效——给文章生成预览索引的脚本解析 frontmatter 时,遇到 CRLF 换行(Windows 编辑器保存的)会解析失败,114 篇的 title 都没读出来,双链 hover 预览几乎全废。改成兼容 CRLF + BOM 后,115 篇全部正常。
  • 装备页图片没有尺寸——防 CLS 的代码里 sharp(fp).metadata() 忘了 await,尺寸 Map 一直是空的,图片加载时会跳动。补上后 5 张装备图都带上了 width/height。
  • 构建明显变快——双向链接索引原来每篇文章渲染时都重建一遍全量索引(复杂度 O(N²)),挪到 getStaticPaths 只建一次,构建从近分钟级回到秒级。

结尾

做博客这件事,最有意思的就是”自己给自己打磨工具”——写文章的人最懂读文章的人需要什么。划词高亮、好用的搜索,都是那种”没有也不会死,有了就回不去”的小功能。

如果你也有博客,Pagefind 值得一试(几分钟接入);划词笔记如果不想自己写,也能找到现成方案。不过话说回来,工具是放大器,不是发电机——真正让博客好的,永远是内容本身。

去正文里随便划一段试试吧。

继续阅读Continue Reading

关于本文About

评论Comments

留下你的想法

欢迎在下方评论区留下你的看法,一起把话题聊得更深。

COMMENTS