Next.js+Framer Motion:监听Link跳转提前移除动画类的方法
解决方案:在Next.js路由跳转前移除动画类
你的问题出在useEffect监听asPath是路由完成变化后才触发状态更新,所以动画会短暂执行。要解决这个问题,需要在路由跳转开始前就移除动画类,具体可以通过自定义拦截跳转的Link组件、监听浏览器前进后退事件来实现:
实现代码
import { useRouter } from 'next/router' import { useState, useEffect } from 'react' import Image from 'next/image' // 自定义拦截跳转的Link组件,替代原生next/link const CustomLink = ({ href, children, setAnimated }) => { const router = useRouter() const handleClick = (e) => { e.preventDefault() // 跳转前立即移除动画类 setAnimated(false) // 可选:如果你的CSS动画有过渡时长,这里加对应延迟再跳转,确保动画完全结束 setTimeout(() => { router.push(href) }, 300) // 300ms对应你的动画时长,可自行调整 } return ( <a href={href} onClick={handleClick}> {children} </a> ) } export default function Projects() { const [animated, setAnimated] = useState(true) const router = useRouter() useEffect(() => { // 处理浏览器前进/后退操作:路由变化前移除动画类 const handleBeforePopState = () => { setAnimated(false) return true // 允许路由正常变化 } router.beforePopState(handleBeforePopState) // 回到/projects页面时,恢复动画状态 const handleRouteComplete = (url) => { if (url === '/projects') { // 延迟恢复,避免页面加载时的动画异常 setTimeout(() => setAnimated(true), 100) } } router.events.on('routeChangeComplete', handleRouteComplete) // 组件卸载时清除监听 return () => { router.beforePopState(() => true) router.events.off('routeChangeComplete', handleRouteComplete) } }, [router]) // 注意:修复你原来的className拼接错误,用空格分隔类名而非+号 return ( <div className={styles.activeLayer}> <Image layout="fill" height='100%' src={allProjects[currentDisplay].backgroundImg} alt="" /> <div className={`${styles.descriptionBox} ${animated ? styles.animatedOne : ''}`}> <h2>SomeTitle</h2> <p>Lorem ipsum dolor sit amet consectetur, adipisicing elit. Modi excepturi esse ex odit saepe ipsam facere beatae similique doloremque quo quidem tempore quas molestias, commodi corporis natus possimus atque voluptatem?</p> <div className={`${styles.iconComponent} ${animated ? styles.animatedFive : ''}`}> <Tool imgArray={allProjects[currentDisplay].tools} /> </div> </div> {/* 使用自定义跳转组件 */} <CustomLink href="/other-page" setAnimated={setAnimated}> 跳转到其他页面 </CustomLink> </div> ) }
关键说明
- 自定义CustomLink:拦截点击事件,先更新
animated状态移除动画类,再执行路由跳转,从根源避免动画短暂执行的问题。 - beforePopState监听:处理浏览器前进/后退操作,同样在路由变化前移除动画类。
- routeChangeComplete恢复状态:回到
/projects页面时,延迟恢复动画状态,确保页面加载完成后动画能正常触发。 - 修复className拼接:原代码中用
+拼接类名是错误的,模板字符串内直接用空格分隔即可正确组合类名。
内容的提问来源于stack exchange,提问作者Mazakina
相关产品推荐
相关产品推荐

