You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 05:27:54