Next.js 14中jQuery的document未定义及动画加载异常问题求助
解决方案
1. 修复「Cannot read properties of undefined (reading 'document')」错误
- 标记使用jQuery/GSAP的组件为客户端组件:在
app/template.tsx顶部添加'use client'指令,确保代码仅在浏览器环境执行(服务端渲染时无document对象,会触发报错)。 - 封装动画初始化函数:将
utils/buttonAnimation.js中的动画逻辑封装为可调用函数,避免模块加载时直接执行(模块加载可能发生在服务端)。
示例代码:
utils/buttonAnimation.js
import $ from 'jquery'; import gsap from 'gsap'; export const initButtonAnimations = () => { // 替换为你的实际动画逻辑 $('.animated-button').hover( function() { gsap.to(this, { scale: 1.08, duration: 0.25, ease: 'power2.out' }); }, function() { gsap.to(this, { scale: 1, duration: 0.25, ease: 'power2.in' }); } ); };
app/template.tsx
'use client'; // 关键:标记为客户端组件 import { useEffect } from 'react'; import { initButtonAnimations } from '@/utils/buttonAnimation'; export default function Template({ children }: { children: React.ReactNode }) { useEffect(() => { // 初始化动画 initButtonAnimations(); // 监听客户端路由跳转,重新初始化动画(避免页面切换后动画失效) const handleRouteChange = () => initButtonAnimations(); window.addEventListener('popstate', handleRouteChange); return () => { window.removeEventListener('popstate', handleRouteChange); }; }, []); return <>{children}</>; }
2. 修复首次加载动画不生效问题
- 使用
useEffect钩子:useEffect仅在客户端Hydrate完成后执行,确保DOM完全可用时初始化动画,解决首次加载时服务端渲染无DOM的问题。 - 可选:使用GSAP Context管理动画,避免内存泄漏:
在useEffect中替换为以下代码:useEffect(() => { const ctx = gsap.context(() => { initButtonAnimations(); }); // 组件卸载时清理动画 return () => ctx.revert(); }, []);
额外注意事项
- 禁止在服务端组件中直接导入jQuery/GSAP:所有依赖浏览器API的库必须在客户端组件中使用。
- 若使用Next.js的
Link组件进行客户端导航,需确保路由变化后重新初始化动画(上述代码中的popstate监听已处理此场景)。
内容的提问来源于stack exchange,提问作者Amir Hossein
相关产品推荐
相关产品推荐

