# 使用 Swup 实现网页平滑过渡 Swup 用于服务器呈现网站的多功能且可扩展的页面过渡库。 ## 缘起 最近看到 Astro ,感觉不错。试了试,虽然感觉生成速度很慢,但是工具链确实很现代化。比如支持 MDX,生成后进行文件压缩,图片转 WebP,少量 js 实现的页面过渡等等功能。 其中比较喜欢 [Astro Paper](https://github.com/satnaing/astro-paper) 和 [Fuwari](https://github.com/saicaca/fuwari) 主题,这两个都有类似 SPA 应用效果,Paper 使用的应该是 Astro4 自带的 API。而 Fuwari,使用的是 Swup 实现的。 [Fuwari Demo](https://fuwari.vercel.app/) 下面进行简单尝试。 ## 信息 官网介绍 > Swup 是一个多功能且可扩展的页面过渡库,适用于 SSR 网站。 它管理整个页面加载生命周期,并在当前和下一个之间平滑地制作动画页。此外,它还提供了许多其他生命周期改进,例如缓存、智能预加载、 本机浏览器历史记录和增强的可访问性。无需复杂操作,即可让您的网站感觉像一个 SPA 单页应用程序。 官网 https://swup.js.org/ 虽然适用于 SSR 网站,但静态博客也能用。 ## 示例 以本博客站点为例, layouts/_default/baseof.html 添加 ```html ``` 这段代码引入了 swup 主要 js 和一个插件。插件主要作用是保证 body ,head js 能够正常运行。(但不保证完全正常) `data-swup-ignore-script` 是告诉插件 `SwupScriptsPlugin` 这段 js 不必重复执行。 除此之外,还需要根据错误,适当修改代码。比如把需要重新执行 js 放到 body ,head 或 main 里。总的来说,增加了页面维护难度。 比如 DoIt 这个主题,我把 `{{- partial "assets.html" . -}}` 放到 `
` 里,评论有时还不会生效。 main 增加 `transition-fade` class 和 id `swup`。 ```html
``` css 增加 ```css html.is-changing .transition-fade { transition: opacity 0.1s; opacity: 1; } /* Define the styles for the unloaded pages */ html.is-animating .transition-fade { opacity: 0; } ``` 忽略控制台报错和一些无法正常工作的脚本还是不错的。按照 4.5.1 版本来看, https://cdn.staticfile.net/swup/4.5.1/Swup.umd.min.js 文件,这个 js 大概 10kb ,未压缩 25kb 左右。插件未压缩不到 3kb 。 ## 类似工具 http://instantclick.io/ 预加载,访问体验优化。并使用 pushState 和 Ajax (pjax) 替换正文。可能会导致部分 js 失效,增加维护难度。5.9kb https://instant.page/ 预加载缓存 4.2kb ## 附件 baseof.html 完整代码参考 ```html {{- partial "init.html" . -}} {{- /* Paginate */ -}} {{- /* Paginate in here, To solve the problem of the canonical URL being the same in the pagination */ -}} {{- /* see more https://github.com/gohugoio/hugo/issues/4507 */ -}} {{- /* see more https://discourse.gohugo.io/t/control-pagination-and-page-collections-from-baseof-html/37643/8 */ -}} {{- /* see more https://discourse.gohugo.io/t/determine-if-current-page-is-result-of-pagination/37494/4 */ -}} {{- partial "head/paginator.html" . -}} {{- block "title" . }}{{ .Site.Title }}{{ end -}} {{- partial "head/meta.html" . -}} {{- partial "head/link.html" . -}} {{- partial "head/seo.html" . -}} {{- $instantpage := .Scratch.Get "instantpage" | default dict -}} {{- if $instantpage.enable -}} {{- end -}} {{- $instantpage := .Site.Params.page.instantpage.enable -}} {{- if $instantpage -}} {{- $js := resources.Get "/lib/instant.page/instantpage.min.js" -}} {{- end -}} {{- /* Check theme isDark before body rendering */ -}} {{- $theme := .Site.Params.defaulttheme -}}
{{- /* Body wrapper */ -}}
{{- partial "header.html" . -}}
{{- block "content" . }}{{ end -}}
{{- /* Load JavaScript scripts and CSS */ -}} {{- partial "assets.html" . -}}
{{- partial "footer.html" . -}}
{{- /* top button */ -}} {{ partial "plugin/fontawesome.html" (dict "Style" "solid" "Icon" "arrow-up") }} {{- /* comment button */ -}} {{ partial "plugin/fontawesome.html" (dict "Style" "solid" "Icon" "comment") }}
```