jQuery指定区域平滑垂直滚动:消除滚动前置像素偏移
解决平滑滚动前置偏移问题
核心问题根源
你的代码未立即阻止原生滚动的默认行为,滚轮触发时浏览器先执行了微小的原生滚动,之后才启动自定义平滑滚动动画,因此出现前置偏移。
具体修复步骤
阻止滚动默认行为
在wheel事件监听中设置passive: false(默认wheel事件为被动监听,无法阻止默认行为),并在事件处理函数开头调用e.preventDefault():document.addEventListener('wheel', handleWheel, { passive: false }); function handleWheel(e) { e.preventDefault(); // 立即阻断原生滚动 // 后续方向判断、目标计算逻辑... }优化方向判断与目标定位
直接通过e.deltaY判断滚动方向(正数向下,负数向上),提前计算目标区块位置,避免依赖window.scrollY的中间偏移:function handleWheel(e) { e.preventDefault(); const direction = e.deltaY > 0 ? 'down' : 'up'; const sections = document.querySelectorAll('.section'); let currentIndex = Array.from(sections).findIndex(section => { const rect = section.getBoundingClientRect(); return rect.top <= 0 && rect.bottom >= window.innerHeight; }); let targetIndex = currentIndex; if (direction === 'down' && currentIndex < sections.length - 1) { targetIndex++; } else if (direction === 'up' && currentIndex > 0) { targetIndex--; } // 平滑滚动到目标区块 sections[targetIndex].scrollIntoView({ behavior: 'smooth', block: 'start' }); }防止重复触发动画
添加锁机制,避免滚动动画过程中重复触发事件:let isScrolling = false; function handleWheel(e) { if (isScrolling) return; e.preventDefault(); isScrolling = true; // 方向判断、目标定位逻辑... sections[targetIndex].scrollIntoView({ behavior: 'smooth', block: 'start' }); // 匹配平滑动画时长,解锁滚动监听 setTimeout(() => { isScrolling = false; }, 800); }
额外优化建议
- 若需兼容移动端触摸滚动,需监听
touchmove事件并阻止默认行为,复用上述方向判断与定位逻辑。 - 自定义平滑动画函数替代原生
behavior: 'smooth',可更精准控制动画曲线与回调时机。
内容的提问来源于stack exchange,提问作者BizMAN
相关产品推荐
相关产品推荐

