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

如何在React中监听document body并转换原生JS滚动交互代码?

React滚动交互逻辑补全方案

核心解决要点

  • 用useState替代全局变量管理激活状态,确保组件状态与渲染同步
  • 通过useEffect绑定/解绑document.body的mouseup事件,避免内存泄漏
  • 用useRef绑定.wrapper元素,替代原生document.querySelector操作DOM

完整实现代码

import { useState, useRef, useEffect } from 'react';

const ScrollComponent = () => {
  const scrollerRef = useRef(null);
  const wrapperRef = useRef(null);
  const [active, setActive] = useState(false);

  const handleMouseDown = () => {
    setActive("middle");
    scrollerRef.current?.classList.add("scrolling");
  };

  const handleMouseUp = () => {
    setActive(false);
    scrollerRef.current?.classList.remove("scrolling");
  };

  // 滚动逻辑函数(根据你的需求实现具体滚动行为)
  const scrollIt = (scrollX) => {
    wrapperRef.current?.scrollTo({
      left: scrollX,
      behavior: 'smooth'
    });
  };

  // 获取wrapper位置并触发滚动(可根据你的触发时机调整调用时机)
  const triggerScroll = () => {
    const wrapperLeft = wrapperRef.current?.getBoundingClientRect().left;
    if (wrapperLeft !== undefined) {
      scrollIt(wrapperLeft);
    }
  };

  // 绑定body的mouseup事件
  useEffect(() => {
    document.body.addEventListener('mouseup', handleMouseUp);
    // 组件卸载时移除监听
    return () => {
      document.body.removeEventListener('mouseup', handleMouseUp);
    };
  }, []);

  return (
    <div className="wrapper" ref={wrapperRef}>
      <div className="middle">
        <img src="images/vr-iootz.jpg" draggable="false" alt="VR场景图" />
      </div>

      <div
        ref={scrollerRef}
        className="scroller scroller-middle"
        onMouseDown={handleMouseDown}
      >
        <svg
          className="scroller__thumb"
          xmlns="http://www.w3.org/2000/svg"
          width="100"
          height="100"
          viewBox="0 0 100 100"
        >
          <polygon points="0 50 37 68 37 32 0 50" fill="rgb(24,24,62)" />
          <polygon points="100 50 64 32 64 68 100 50" fill="rgb(24,24,62)" />
        </svg>
      </div>
    </div>
  );
};

export default ScrollComponent;

关键细节说明

  1. 状态管理:用useState维护active状态,替代全局变量,确保状态变化能触发组件正确渲染
  2. 事件监听:通过useEffect在组件挂载时添加mouseup监听,卸载时自动移除,避免内存泄漏
  3. 安全DOM操作:使用可选链操作符?.判断ref的current是否存在,防止空指针报错
  4. 元素绑定:给.wrapper添加useRef,直接通过wrapperRef.current获取元素,符合React组件化DOM操作规范

内容的提问来源于stack exchange,提问作者Kiki-ko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 15:47:07