React中如何准确检测滚轮向上或向下滚动?
React中onWheel事件判断滚动方向异常的解决方法
问题原因
向上滚动时同时打印上下滚动日志,通常是以下两种情况导致:
- 单次滚动动作中,浏览器因鼠标滚轮微小抖动或平滑滚动机制触发多次
WheelEvent,deltaY出现正负交替值,触发了不同分支的判断。 - 父元素或嵌套元素也绑定了
onWheel事件,事件冒泡导致处理函数被多次调用。
解决方案
1. 严谨判断方向并阻止事件冒泡
使用Math.sign()明确获取滚动方向的正负值,同时通过event.stopPropagation()避免事件冒泡重复触发:
const handleOnWheel = (event: React.WheelEvent<HTMLDivElement>) => { event.stopPropagation(); const scrollDirection = Math.sign(event.deltaY); if (scrollDirection === -1) { console.log('Scrolling up'); } else if (scrollDirection === 1) { console.log('Scrolling down'); } };
2. 添加防抖处理过滤重复触发
针对浏览器多次触发事件的问题,用防抖函数限制处理逻辑的执行频率,确保一次滚动只触发一次判断:
import { useCallback, useRef } from 'react'; const YourComponent = () => { const timeoutRef = useRef<NodeJS.Timeout | null>(null); const handleOnWheel = useCallback((event: React.WheelEvent<HTMLDivElement>) => { const scrollDirection = Math.sign(event.deltaY); if (timeoutRef.current) clearTimeout(timeoutRef.current); timeoutRef.current = setTimeout(() => { if (scrollDirection === -1) { console.log('Scrolling up'); } else if (scrollDirection === 1) { console.log('Scrolling down'); } }, 50); }, []); return <div onWheel={handleOnWheel}>滚动测试区域</div>; };
3. 记录上次滚动方向避免重复输出
通过useRef记录上一次的滚动方向,仅当方向变化时才执行日志输出:
import { useCallback, useRef } from 'react'; const YourComponent = () => { const lastDirection = useRef<number | null>(null); const handleOnWheel = useCallback((event: React.WheelEvent<HTMLDivElement>) => { const scrollDirection = Math.sign(event.deltaY); if (scrollDirection !== lastDirection.current) { lastDirection.current = scrollDirection; if (scrollDirection === -1) { console.log('Scrolling up'); } else if (scrollDirection === 1) { console.log('Scrolling down'); } } }, []); return <div onWheel={handleOnWheel}>滚动测试区域</div>; };
内容的提问来源于stack exchange,提问作者Nyi Nyi Hmue Aung
相关产品推荐
相关产品推荐

