音乐播放器写了1400行之后,我觉得剩下的东西应该都是小活了吧。暗色模式?加个class。导航栏?固定在顶部。搜索?弹个框。结果没有一个真正”随便搞搞就行”。
暗色模式的闪屏

暗色模式做起来不难——Tailwind 加个 dark: 前缀就行。配合 localStorage 记住用户的选择,配合时间判断自动切换(18:00-6:00 暗色)。
但跟 View Transitions 结合的时候就出问题了。
Astro 的 ClientRouter 在页面导航时会做一件事:把新页面的 <html> 属性替换到当前页面。而新页面是服务端渲染的,<html> 标签上没有 class="dark"——因为暗色模式是客户端 JavaScript 加上去的。
所以每次导航,暗色模式就丢了。页面会闪一下白色,然后 JavaScript 执行后才恢复暗色。
修复方法是监听 astro:after-swap 事件——这个事件在 DOM 替换后、页面渲染前触发。在这个时机从 localStorage 读取主题设置,立刻把 dark class 加回去。这样就不会有闪屏了。
这个 bug 找了很久才定位到。因为表现是”有时候暗色模式正常,有时候不正常”——取决于你是直接打开页面(正常)还是通过导航跳转(不正常)。这种时灵时不灵的 bug 是最折磨人的。
导航栏透明的问题
一开始导航栏用的是毛玻璃效果——半透明背景 + backdrop-filter: blur()。
看起来很好看对吧?问题是往下滚动的时候,文章内容会从导航栏下方透出来。特别是标题之类的大字,跟导航栏的文字叠在一起,根本看不清。
后来改成了实底背景——bg-white/95,几乎不透明但还保留一点点通透感。同时加了下滑自动隐藏、上滑显示的逻辑。
自动隐藏的实现也有坑。要检测滚动方向(当前 scrollY 跟上次比较),设阈值防抖(不然轻微抖动就会反复显示隐藏),还要处理顶部区域(滚动到最顶部时必须显示导航栏)。
进度条也要跟着导航栏一起动——导航栏隐藏时进度条也要跟着往上走。两个元素的 transform: translateY() 要同步。
导航栏总算消停了。然后打开手机一看——
Material Icons 翻车

一开始用 Google 的 Material Symbols 图标字体。在 HTML 里写 <span class="material-symbols-outlined">home</span>,字体加载后会显示对应的图标。
问题是——字体加载失败的时候,页面上就会显示一堆英文。
手机底部导航变成了:“home” “article” “inventory_2” “sports_esports” “person”。
完全不能接受。
最后全部换成了 SVG 内联图标。虽然 HTML 变长了,但至少不依赖外部字体加载,永远不会显示英文。同时删掉了 Material Symbols 的字体引入,少加载一个外部请求,页面加载也变快了。
搜索

搜索功能一开始做成了弹窗(overlay)——点击搜索按钮弹出一个全屏遮罩,中间一个搜索框。
后来被吐槽了:为什么要单独弹一个界面?很打断体验。
改成了内嵌式——搜索面板从导航栏下方展开,不遮挡页面其他内容。搜索数据是构建时生成的 JSON(/search.json),客户端加载后用简单的字符串匹配做模糊搜索。
没用 Algolia 或 Fuse.js 之类的库,因为文章才十几篇,简单的 indexOf 就够用了。等文章多到几百篇再考虑换。
搜索结果直接显示文章标题、封面缩略图、日期和标签,点击跳转。
搜索就这样了。
弹幕视频播放器
凉宫春日那篇文章里有一个 GOD KNOWS 的弹幕视频播放器。用的是 DPlayer 库 + 2199 条真实的 B 站弹幕数据。
这个功能做的时候也有坑——还是 View Transitions。
DPlayer 用 DOMContentLoaded 事件初始化。软导航不会触发这个事件。所以第一次打开文章页视频正常显示,离开后再回来,视频就没了。
修复方法跟其他脚本一样——加 astro:page-load 监听。另外还加了跟音乐播放器的联动:视频播放时自动暂停 BGM,视频暂停后恢复。靠 CustomEvent 互相喊一嗓子,谁也不用知道对方怎么写的。
到这里网站功能基本成型了。然后某天我把链接发到群里,发现分享出去只有一个干巴巴的 URL,没有标题预览也没有封面图。
哦,对了,SEO。
SEO
最开始完全没管这个。
后来花了半天把分享预览、站点地图、RSS 那些东西一口气全加完。发到群里一看——有封面有标题有摘要,终于像个正经网站了。
搭博客的感受
做之前以为都是小活,做完发现每个功能自己能跑,但放在一起就打架。暗色模式跟 View Transitions 打,导航栏跟进度条打,视频播放器跟音乐播放器打。大部分时间不是在写功能,是在当和事佬。
不过现在打开自己的网站看看,还行,没白折腾。
你可能还想看