Astro 博客添加 View Transitions 实现丝滑页面切换
为 Astro 静态博客添加 View Transitions API,实现类似 SPA 的快速页面导航体验,并解决暗色模式闪烁问题
为 Astro 静态博客添加 View Transitions API,实现类似 SPA 的快速页面导航体验,并解决暗色模式闪烁问题
Astro 默认采用 MPA(多页面应用) 架构,每次点击链接都会进行完整的页面刷新。虽然这种方式对 SEO 友好,但用户体验上会感觉有些”卡顿”,尤其是与 Next.js、Nuxt 等 SPA 框架相比。
Astro 从 v3.0 开始支持 View Transitions API,可以实现:
在 BaseHead.astro(或你的 <head> 组件)中添加:
---
import { ClientRouter } from 'astro:transitions';
---
<!-- 在 head 中添加 -->
<ClientRouter />
就这么简单!现在页面切换时会有平滑的淡入淡出效果。
启用 View Transitions 后,你可能会发现一个问题:切换页面时暗色模式会闪白。
这是因为客户端导航时,新页面的 DOM 会替换旧页面,但主题初始化脚本(is:inline)只在首次加载时执行。
解决方案:使用 astro:before-swap 事件,在 DOM 交换之前将主题类应用到新文档:
<script is:inline>
// 判断当前是否应该使用暗色模式
function shouldBeDark() {
const theme = localStorage.getItem('theme') || 'system';
if (theme === 'dark') return true;
if (theme === 'light') return false;
return window.matchMedia('(prefers-color-scheme: dark)').matches;
}
// 应用主题到指定的文档元素
function applyThemeToDocument(doc) {
if (shouldBeDark()) {
doc.documentElement.classList.add('dark');
} else {
doc.documentElement.classList.remove('dark');
}
}
// 初始加载时立即应用主题
applyThemeToDocument(document);
// View Transitions: 在 DOM 交换前将主题应用到新文档
document.addEventListener('astro:before-swap', (event) => {
applyThemeToDocument(event.newDocument);
});
</script>
关键点:
astro:before-swap 而非 astro:after-swapevent.newDocument 访问即将替换进来的新文档| 事件 | 触发时机 | 用途 |
|---|---|---|
astro:before-preparation | 导航开始前 | 获取新页面前 |
astro:after-preparation | 新页面加载后 | 新 DOM 准备好 |
astro:before-swap | DOM 交换前 | 重新应用状态(推荐) |
astro:after-swap | DOM 交换后 | 初始化新 DOM |
astro:page-load | 页面完全加载 | 初始化组件 |
<!-- 给元素添加共享动画名称 -->
<h1 transition:name="title">页面标题</h1>
<!-- 指定动画类型 -->
<div transition:animate="slide">滑动进入</div>
<div transition:animate="fade">淡入淡出</div>
<!-- 在页面切换时保持元素状态(如视频播放进度) -->
<video transition:persist>...</video>
通过简单的配置,Astro 博客也能拥有类似 SPA 的丝滑体验。核心要点:
<ClientRouter /> 组件启用客户端路由astro:before-swap 事件处理状态持久化Astro 博客添加 View Transitions 实现丝滑页面切换
www.jsom.top/post/astro-博客添加-view-transitions-实现丝滑页面切换
Comments