如何实现鼠标滚动时的平滑页面滚动效果?
鼠标滚轮平滑滚动实现方案
核心思路
要解决滚轮滚动跳帧、实现平滑效果,核心是阻止浏览器原生滚动行为,通过JavaScript监听滚轮事件计算滚动距离,再用动画方式逐步调整页面滚动位置,以此替代原生的瞬时滚动。
具体实现步骤
1. 基础HTML结构示例
<div class="scroll-wrap"> <div class="page-content"> <!-- 填充足够长的页面内容,确保可滚动 --> </div> </div>
2. CSS 基础配置
隐藏原生滚动条,固定容器视口,避免和自定义滚动逻辑冲突:
.scroll-wrap { height: 100vh; overflow: hidden; position: relative; } .page-content { position: absolute; top: 0; left: 0; width: 100%; }
3. JavaScript 实现逻辑
利用requestAnimationFrame实现流畅动画,同时处理滚动边界与事件防抖:
const scrollWrap = document.querySelector('.scroll-wrap'); const pageContent = document.querySelector('.page-content'); let isAnimating = false; let currentScroll = 0; const smoothFactor = 0.18; // 平滑系数,数值越小滚动越平缓 // 监听滚轮事件 scrollWrap.addEventListener('wheel', (e) => { e.preventDefault(); const scrollDelta = e.deltaY; if (!isAnimating) { isAnimating = true; startSmoothScroll(scrollDelta); } }); function startSmoothScroll(delta) { const targetScroll = currentScroll + delta; // 限制滚动范围,防止内容超出可视区域 const maxScroll = pageContent.offsetHeight - scrollWrap.offsetHeight; const clampedTarget = Math.max(0, Math.min(targetScroll, maxScroll)); function animateScroll() { currentScroll += (clampedTarget - currentScroll) * smoothFactor; pageContent.style.top = `-${currentScroll}px`; // 距离目标位置足够近时停止动画 if (Math.abs(clampedTarget - currentScroll) < 0.3) { currentScroll = clampedTarget; pageContent.style.top = `-${currentScroll}px`; isAnimating = false; return; } requestAnimationFrame(animateScroll); } animateScroll(); }
4. 优化细节
- 防抖处理:通过
isAnimating标记避免滚轮连续触发导致动画叠加,提升性能。 - 边界控制:限制滚动范围,确保内容不会滚出容器可视区域。
- 兼容性:
wheel事件支持主流浏览器,若需兼容旧版IE,可补充监听mousewheel事件(注意事件参数差异)。 - 自定义调整:修改
smoothFactor可调整平滑度,数值越大滚动速度越快、平滑度越低,反之则更平缓。
简易替代方案(局限性)
如果不需要精细控制滚动逻辑,可尝试CSS原生属性,但它仅对原生滚动生效,无法自定义动画曲线和速率:
html { scroll-behavior: smooth; }
内容的提问来源于stack exchange,提问作者Damian_B
相关产品推荐
相关产品推荐

