Astro

Astro 博客添加 View Transitions 实现丝滑页面切换

为 Astro 静态博客添加 View Transitions API,实现类似 SPA 的快速页面导航体验,并解决暗色模式闪烁问题

Astro 博客添加 View Transitions 实现丝滑页面切换

问题背景

Astro 默认采用 MPA(多页面应用) 架构,每次点击链接都会进行完整的页面刷新。虽然这种方式对 SEO 友好,但用户体验上会感觉有些”卡顿”,尤其是与 Next.js、Nuxt 等 SPA 框架相比。

解决方案:View Transitions

Astro 从 v3.0 开始支持 View Transitions API,可以实现:

  • 客户端路由 - 点击链接不刷新整个页面
  • 平滑过渡动画 - 页面切换时有淡入淡出效果
  • 共享元素动画 - 相同元素可在页面间保持

1. 添加 ClientRouter 组件

BaseHead.astro(或你的 <head> 组件)中添加:

---
import { ClientRouter } from 'astro:transitions';
---

<!-- 在 head 中添加 -->
<ClientRouter />

就这么简单!现在页面切换时会有平滑的淡入淡出效果。

2. 修复暗色模式闪烁问题

启用 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-swap
  • 通过 event.newDocument 访问即将替换进来的新文档
  • 在交换前就设置好主题类,避免闪烁

View Transitions 生命周期事件

事件触发时机用途
astro:before-preparation导航开始前获取新页面前
astro:after-preparation新页面加载后新 DOM 准备好
astro:before-swapDOM 交换前重新应用状态(推荐)
astro:after-swapDOM 交换后初始化新 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 的丝滑体验。核心要点:

  1. 引入 <ClientRouter /> 组件启用客户端路由
  2. 使用 astro:before-swap 事件处理状态持久化
  3. 注意在 DOM 交换应用主题,避免闪烁

参考资料

Astro 博客添加 View Transitions 实现丝滑页面切换

www.jsom.top/post/astro-博客添加-view-transitions-实现丝滑页面切换

👋

13 篇文章

38 个话题

2,157 次访问

Comments