React打字测试应用实现自动滚动文本效果的方案咨询
实现自动滚动效果的解决方案
步骤1:给文本容器添加滚动样式
先修改typingField的CSS,让它成为可滚动容器:
.typingField { height: 200px; /* 可根据需求调整高度 */ overflow-y: auto; padding: 1rem; text-align: left; }
步骤2:添加当前单词的引用
在组件中新增一个currentWordRef,用来追踪当前正在输入的单词元素:
const ref = useRef(null); const currentWordRef = useRef(null); // 新增引用
步骤3:绑定ref到当前单词
在渲染单词的逻辑里,当currentWord为true时,把ref绑定到对应的span上:
<span key={wordIndex} ref={currentWord ? currentWordRef : null} // 绑定引用 className={`${highlight && "green"} ${currentWord && "underline"} word`} > {/* 原有字母渲染逻辑 */} </span>
步骤4:实现自动滚动逻辑
添加useEffect监听输入状态变化,当当前单词接近容器底部时触发自动滚动:
useEffect(() => { if (!currentWordRef.current) return; const container = document.getElementById('text-container'); if (!container) return; const wordElement = currentWordRef.current; const containerRect = container.getBoundingClientRect(); const wordRect = wordElement.getBoundingClientRect(); // 当单词底部距离容器底部不足50px时触发滚动(阈值可调整) const distanceToBottom = containerRect.bottom - wordRect.bottom; if (distanceToBottom < 50) { wordElement.scrollIntoView({ behavior: 'smooth', block: 'start' // 让单词顶部对齐容器顶部,也可选'center'居中 }); } }, [completed, input]);
完整修改后的核心代码片段
export default function Main(props) { // 原有state和ref const [text, setText] = useState(""); const [input, setInput] = useState(""); // ...其他state... const ref = useRef(null); const currentWordRef = useRef(null); // 新增的引用 // 新增自动滚动的useEffect useEffect(() => { if (!currentWordRef.current) return; const container = document.getElementById('text-container'); if (!container) return; const wordElement = currentWordRef.current; const containerRect = container.getBoundingClientRect(); const wordRect = wordElement.getBoundingClientRect(); const distanceToBottom = containerRect.bottom - wordRect.bottom; if (distanceToBottom < 50) { wordElement.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }, [completed, input]); // 原有渲染逻辑中修改单词的span return ( {/* ...其他渲染内容... */} <span key={wordIndex} ref={currentWord ? currentWordRef : null} className={`${highlight && "green"} ${currentWord && "underline"} word`} > {word.split("").map((letter, letterIndex) => { // 原有字母渲染逻辑 })} </span> ) }
修改完成后,当输入到接近容器底部的单词时,容器会自动平滑滚动,展示后续内容,和Monkeytype的效果一致。
内容的提问来源于stack exchange,提问作者HC2102
相关产品推荐
相关产品推荐

