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

ReactJS如何实现滚动时div从左向右移动且停留在所属区块内

实现代码

JSX 部分

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

// 可根据自身需求调整以下常量
const ROOT_FONT_SIZE = 16 // 项目根元素font-size,默认浏览器为16px
const INITIAL_LEFT = 2 // 圆形初始左侧位置,单位rem
const MOVE_SPEED = 5 // 移动速度,数值越大移动越慢

function App() {
  const [position, setPosition] = useState(INITIAL_LEFT)
  const sectionRef = useRef(null)
  const circleRef = useRef(null)
  const maxLeftRef = useRef(0)

  // 页面加载完成后计算圆形可移动的最大右边界
  useEffect(() => {
    const sectionWidth = sectionRef.current.offsetWidth
    const circleWidth = circleRef.current.offsetWidth
    maxLeftRef.current = (sectionWidth - circleWidth) / ROOT_FONT_SIZE
  }, [])

  function moveCircle() {
    const scrollTop = window.pageYOffset
    const candidatePosition = scrollTop / MOVE_SPEED
    // 仅新位置大于当前位置且未超出边界时更新,实现向上滚动不回退
    if (candidatePosition > position && candidatePosition < maxLeftRef.current) {
      setPosition(candidatePosition)
    } 
    // 到达右边界后固定位置不再移动
    else if (candidatePosition >= maxLeftRef.current && position !== maxLeftRef.current) {
      setPosition(maxLeftRef.current)
    }
  }

  useEffect(() => {
    const scrollHandler = () => requestAnimationFrame(moveCircle)
    window.addEventListener('scroll', scrollHandler, false)
    // 组件卸载时清理滚动监听,避免内存泄漏
    return () => window.removeEventListener('scroll', scrollHandler)
  }, [position])

  return (
    <div className="App">
      <div className="sectionOne" ref={sectionRef}>
        <div 
          className="circle styles" 
          ref={circleRef}
          style={{ position: 'absolute', left: `${position}rem` }}
        ></div>
      </div>
      <div className="sectionTwo"></div>
    </div>
  )
}

export default App

CSS 补充

.sectionOne {
  position: relative; /* 必须设置,保证圆形相对于当前区块定位 */
  height: 150vh; /* 可自行调整高度,需要足够的滚动空间触发圆形移动 */
  width: 100%;
}
.circle {
  /* 以下为示例样式,可根据需求修改 */
  width: 4rem;
  height: 4rem;
  border-radius: 50%;
  background-color: #2563eb;
  top: 50%;
  transform: translateY(-50%);
}

关键逻辑说明

  • 父容器必须设置position: relative,否则圆形的绝对定位会相对于整个页面,而非所属区块
  • 通过useRef获取容器和圆形的实际宽度,自动计算最大可移动右边界,保证圆形不会超出所属区块范围
  • 位置更新时新增两个判断:仅向下滚动(新位置大于当前位置)时更新,向上滚动位置不变;到达右边界后直接固定位置,不会滚动出页面
  • 新增滚动事件清理逻辑,避免组件卸载后内存泄漏

内容的提问来源于stack exchange,提问作者monkeys773

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 21:57:03