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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 14:54:50