React/NextJS 基于计时器的文本淡入淡出效果失效问题求助
解决词汇淡入淡出动画失效问题
问题定位及修复步骤
1. 修复CSS模块类名引用错误
你的JS代码中,span的className写法错误:
<span className={`styles.${fadeProp}`}>
CSS模块导出的是对象,不能用字符串拼接访问属性,需改用对象属性访问方式:
<span className={styles[fadeProp]}>
2. 修正CSS重复定义错误
CSS里重复定义了.fadein选择器,第二个会覆盖第一个,导致fadein类实际执行fadeout动画,将第二个选择器改为.fadeout,同时添加forwards关键字保持动画结束状态:
.fadein { animation: fadein 0.3s forwards; -moz-animation: fadein 0.3s forwards; -webkit-animation: fadein 0.3s forwards; -o-animation: fadein 0.3s forwards; } .fadeout { animation: fadeout 0.3s forwards; -moz-animation: fadeout 0.3s forwards; -webkit-animation: fadeout 0.3s forwards; -o-animation: fadeout 0.3s forwards; }
3. 优化定时器逻辑(提升稳定性)
原代码依赖fadeProp的useEffect会重复创建定时器,易导致叠加冲突。合并逻辑用单一流程控制动画:
export default function AnimatedText() { const [currentWordIndex, setCurrentWordIndex] = useState(0); const [fadeState, setFadeState] = useState('fadein'); useEffect(() => { const cycleAnimation = () => { // 保持淡入状态一段时间 setTimeout(() => { setFadeState('fadeout'); // 淡出完成后切换词汇并触发淡入 setTimeout(() => { setCurrentWordIndex(prev => (prev + 1) % WORDS_TO_ANIMATE.length); setFadeState('fadein'); cycleAnimation(); }, 300); // 与动画时长0.3s对应 }, 1700); // 总周期2000ms = 显示时长1700ms + 动画时长300ms }; cycleAnimation(); }, []); return ( <h2 className={styles.white}> <span className={styles[fadeState]}> {WORDS_TO_ANIMATE[currentWordIndex]} </span> , I'm bleh. </h2> ); }
完整修复后代码
index.js
import { useEffect, useState } from 'react'; import styles from './index.module.css'; const ANIMATION_DURATION_MS = 300; const WORD_DISPLAY_DURATION_MS = 1700; const WORDS_TO_ANIMATE = [ 'Hello', 'Ciao', 'Jambo', 'Bonjour', 'Salut', 'Hola', 'Nǐ hǎo', 'Hallo', 'Hej', '👋🏻', ]; export default function AnimatedText() { const [currentWordIndex, setCurrentWordIndex] = useState(0); const [fadeState, setFadeState] = useState('fadein'); useEffect(() => { const cycleAnimation = () => { setTimeout(() => { setFadeState('fadeout'); setTimeout(() => { setCurrentWordIndex(prev => (prev + 1) % WORDS_TO_ANIMATE.length); setFadeState('fadein'); cycleAnimation(); }, ANIMATION_DURATION_MS); }, WORD_DISPLAY_DURATION_MS); }; cycleAnimation(); }, []); return ( <h2 className={styles.white}> <span className={styles[fadeState]}> {WORDS_TO_ANIMATE[currentWordIndex]} </span> , I'm bleh. </h2> ); }
index.module.css
.fadein { animation: fadein 0.3s forwards; -moz-animation: fadein 0.3s forwards; -webkit-animation: fadein 0.3s forwards; -o-animation: fadein 0.3s forwards; } .fadeout { animation: fadeout 0.3s forwards; -moz-animation: fadeout 0.3s forwards; -webkit-animation: fadeout 0.3s forwards; -o-animation: fadeout 0.3s forwards; } .white { color: silver; } @keyframes fadein { 0% { opacity: 0; } 100% { opacity: 1; } } @keyframes fadeout { 0% { opacity: 1; color: blue; } 100% { opacity: 0; color: red; } }
内容的提问来源于stack exchange,提问作者Zachary Hogna
相关产品推荐
相关产品推荐

