建站日志 #3:暗色模式、导航栏、搜索和那些琐碎的事

建站日志 #3:暗色模式、导航栏、搜索和那些琐碎的事

2026/3/5 · 阿幻 · 约 6 分钟 · - 次阅读
📖 建站日志 · 第 3 / 2 篇
← 上一篇|下一篇 →

音乐播放器写了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 的字体引入,少加载一个外部请求,页面加载也变快了。

 

搜索

搜索面板 - Ctrl+K 快捷搜索

搜索功能一开始做成了弹窗(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 打,导航栏跟进度条打,视频播放器跟音乐播放器打。大部分时间不是在写功能,是在当和事佬。

不过现在打开自己的网站看看,还行,没白折腾。

分享这篇文章

💬

留言板

( ´▽` )ノ 来聊聊吧~
载入中...
幻之空
0:00
0:00