网站加载动画实现
- W_Z_C
- 共 851 字,阅读约 2 分钟
本篇文章主要介绍如何在现有的网站上添加加载动画。加载动画对于网站来说并不是必须的,但是因为 Nextjs 在网页切换的时候会在后台动态加载页面数据,如果页面数据量较大,或者网络条件糟糕的情况下,会让用户感觉点击没有生效,根本原因是在加载的过程中没有一个明确的反馈信息,今天介绍的加载动画就是为了缓解这个问题。
想要实现加载动画效果,需要借助 Nextjs 的路由系统。在路由系统上你可以监听一系列的事件:
routeChangeStart(url, { shallow })
,当路由开始改变的时候触发。routeChangeComplete(url, { shallow })
,当路由完成改变的时候触发。routeChangeError(err, url, { shallow })
,当路由加载失败的时候触发。
目前主要监听了上面的三个路由事件。在路由开始改变的时候,显示加载动画,当完成或者发生错误的时候隐藏动画。
1. 动画加载组件
实现加载动画首先要创建一个前端组件,用它来承载动画内容:
Loading.js
import { Transition } from '@headlessui/react'
import { Fragment } from 'react'
export default function Loading({ loading }) {
return (
<Transition
show={loading}
as={Fragment}
enter="transition ease-in-out duration-300 transform"
enterFrom="-translate-y-full"
enterTo="translate-y-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="translate-y-0"
leaveTo="-translate-y-full"
>
<div className="w-screen h-screen absolute z-50 bg-white">
<div className="absolute left-0 right-0 top-0 bottom-0 m-auto text-center h-12 md:h-14">
<img src="/assert/images/logo.png" className="m-auto h-12 md:h-14 transition-transform animate-spin" alt="Loading..." />
<div className="pt-2 animate-pulse">Loading...</div>
</div>
</div>
</Transition>
)
}
代码很简单就是单纯的显示了一个 logo,并弄了个旋转动画效果。
2. 监听路由事件
接下来就是前面提到的监听路由事件:
_app.js
import { useRouter } from 'next/router'
import { useEffect, useState } from 'react'
import '../styles/globals.css'
function MyApp({ Component, pageProps }) {
const router = useRouter()
const [loading, setLoading] = useState(false)
useEffect(() => {
const handleChangeStart = (url) => {
setLoading(true)
}
const handleChangeComplete = (url) => {
setLoading(false)
}
router.events.on('routeChangeStart', handleChangeStart)
router.events.on('routeChangeComplete', handleChangeComplete)
router.events.on('routeChangeError', handleChangeComplete)
return function cleanup() {
router.events.off('routeChangeStart', handleChangeStart)
router.events.off('routeChangeComplete', handleChangeComplete)
router.events.off('routeChangeError', handleChangeComplete)
}
}, [router])
return <Component {...pageProps} />
}
组件中创建了一个 loading 状态,当路由开始切换的时候,则设置该状态值为 true,当完成的时候将其重置为 false,在以后的代码中,可以根据该状态的值来判断网站是否处于加载状态。
3. 显示加载组件
接着修改原来的函数返回值,将 Loading 组件添加进去,并且设置加载状态下隐藏主界面。
_app.js
function MyApp({ Component, pageProps }) {
//...
return (
<>
<Loading loading={loading} />
<main className={loading ? "hidden" : "block"}>
<Component {...{ ...pageProps, loading }} />
</main>
</>
)
}
加载动画的实现还是很简单的,不过注意一下最后的代码,我们将 loading 状态传入了子组件 Component 的内部,这是因为在显示页面的过程中,可能会用到这个状态值,所以特意添加进去。