如何修复React实现滚动触发开帘动画遇到的两个问题
问题解决方案
你遇到的两个问题均可通过将滚动位移与元素在视口的滚动进度直接绑定的方案一次性解决,不需要额外判断滚动方向,也能自动限制动效边界,修改逻辑如下:
- 移除冗余的滚动方向判断逻辑,改用滚动进度计算位移值,动效会跟随滚动位置自然同步,不会出现反向移动的问题
- 给位移值增加0到最大展开距离的边界限制,超过预设动效范围后自动停止,不会无限运行
完整修改后代码
import { useState, useEffect, useRef, useCallback } from "react"; import "./styles.css"; // 窗帘最大拉开距离,可根据你的布局需求调整 const MAX_TRANSLATE = 500; export default function App() { const boxTwo = useRef(null); const boxTwoLeft = useRef(null); const boxTwoRight = useRef(null); const countRefTranslateX = useRef(0); const handleScroll = useCallback(() => { if (!boxTwo.current) return; const position = boxTwo.current.getBoundingClientRect(); const viewportHeight = window.innerHeight; // 计算滚动进度:0=动效未开始,1=动效完全结束 // 规则:boxTwo顶部进入视口时开始,boxTwo底部离开视口时结束,可自行调整公式修改启停断点 const scrollProgress = Math.max(0, Math.min(1, (viewportHeight - position.top) / (viewportHeight + position.height) )); const translateX = scrollProgress * MAX_TRANSLATE; countRefTranslateX.current = translateX; boxTwoLeft.current.style.transform = `translateX(-${translateX}px)`; boxTwoRight.current.style.transform = `translateX(${translateX}px)`; }, []); useEffect(() => { window.addEventListener("scroll", handleScroll); return () => window.removeEventListener("scroll", handleScroll); }, [handleScroll]); return ( <div className="App"> <div className="boxOne"></div> <div ref={boxTwo} className="boxTwo"> <div ref={boxTwoLeft} className="boxTwoLeft"></div> <div ref={boxTwoRight} className="boxTwoRight"></div> </div> <div className="boxThree"></div> </div> ); }
自定义调整说明
如果需要修改动效的启停断点,只需要调整scrollProgress的计算公式即可:
- 若想元素进入视口200px后才开始动效,可把
(viewportHeight - position.top)修改为(viewportHeight - position.top - 200) - 若想动效在元素完全进入视口时就全部展开,可把分母
(viewportHeight + position.height)修改为position.height
内容的提问来源于stack exchange,提问作者dev_el
相关产品推荐
相关产品推荐

