React实现文本淡出替换再淡入效果报错:fadeIn不是函数
问题描述
我有一组<p>标签,想要实现循环切换效果:淡入一个<p>标签,随后淡出,替换内容后再次淡入。尝试用React的useEffect编写代码实现时出现报错:
Uncaught TypeError: document.querySelectorAll(...)[(quoteIndex % quotes.length)].fadeIn is not a function
相关代码如下:
useEffect代码
useEffect(() => { (function() { var quotes = document.getElementsByClassName('tagline-text'); var quoteIndex = -1; function showNextQuote() { ++quoteIndex; document.querySelectorAll(".tagline-text")[quoteIndex % quotes.length].fadeIn(1000).delay(1000).fadeOut(1000, showNextQuote); } showNextQuote(); })(); }, []);
容器代码
<div className="tagline h-100 d-flex flex-column align-items-center justify-content-center"> <p className="tagline-text">Your Business</p> <p className="tagline-text">Your Brand</p> <p className="tagline-text">Your Content</p> <p className="tagline-text">Your Portfolio</p> <p className="tagline-text">You.</p> </div>
解决方案
错误原因
fadeIn()、delay()、fadeOut()是jQuery专属方法,原生DOM元素并没有这些API,直接调用自然会报错。在React项目中,更推荐用状态驱动+CSS过渡的方式实现效果,避免直接操作DOM。
实现思路
- 用状态
currentIndex跟踪当前显示的文本索引 - 用状态
isVisible控制文本的显示/隐藏状态 - 配合
setTimeout切换状态,实现循环逻辑 - 用CSS的
transition属性实现平滑淡入淡出动画
完整代码实现
import { useEffect, useState } from 'react'; function TaglineSlider() { const quotes = ["Your Business", "Your Brand", "Your Content", "Your Portfolio", "You."]; const [currentIndex, setCurrentIndex] = useState(0); const [isVisible, setIsVisible] = useState(true); useEffect(() => { // 显示指定时长后触发淡出 const fadeOutTimer = setTimeout(() => { setIsVisible(false); // 淡出完成后切换索引并触发淡入 const fadeInTimer = setTimeout(() => { setCurrentIndex(prev => (prev + 1) % quotes.length); setIsVisible(true); }, 1000); // 淡出动画时长 return () => clearTimeout(fadeInTimer); }, 1000); // 文本停留时长 return () => clearTimeout(fadeOutTimer); }, [currentIndex, isVisible]); return ( <div className="tagline h-100 d-flex flex-column align-items-center justify-content-center" style={{position: 'relative'}}> <p className="tagline-text" style={{ opacity: isVisible ? 1 : 0, transition: 'opacity 1s ease-in-out', position: 'absolute', margin: 0 }} > {quotes[currentIndex]} </p> </div> ); } export default TaglineSlider;
补充说明
- 合并多个
<p>标签为单个,通过状态切换内容,更符合React状态驱动的设计理念 - 用CSS过渡实现动画,比直接操作DOM更高效且易维护
- 加入定时器清理逻辑,避免组件卸载后出现内存泄漏
- 如果需要保留多标签结构,也可以通过控制每个标签的
opacity状态实现,但单标签切换的方式更简洁
内容的提问来源于stack exchange,提问作者Shourya Shikhar
相关产品推荐
相关产品推荐

