2026-10-23 10:36:40
在 JavaScript 中,可以通过结合 scrollTop 属性、requestAnimationFrame 方法和时间差计算,实现自定义滚动速度和距离的平滑滚动效果。以下是具体实现步骤和代码示例:
核心实现步骤获取起始与目标位置
使用 window.pageYOffset 获取当前垂直滚动位置。
目标位置可通过事件(如鼠标滚轮)或固定值设定。
计算滚动距离
目标位置减去当前位置得到总滚动距离(distance = target - start)。
控制滚动速度
通过 requestAnimationFrame 实现动画循环,结合时间差(progress)计算每帧滚动位置。
使用线性插值公式:当前滚动位置 = (进度/总时间) * 总距离 + 起始位置。
终止条件
当动画持续时间(progress)超过设定值(duration)时停止循环。
requestAnimationFrame比 setTimeout 更高效,能同步浏览器重绘,避免卡顿。
时间控制duration 参数决定滚动总时间(如1000ms=1秒),值越大滚动越慢。
线性插值公式scrollY = start + distance * (progress/duration) 确保滚动速度均匀。
用户体验优化
避免在滚动过程中触发其他高耗能操作。
移动端需测试触摸事件兼容性。
提供关闭自定义滚动的选项(如通过按钮切换)。
缓动效果修改插值公式为非线性函数(如二次缓动):
const easeInOut = (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;const scrollY = startPosition + distance * easeInOut(percentage);滚动到元素结合 element.offsetTop 实现滚动到指定元素:
function scrollToElement(elementId) { const element = document.getElementById(elementId); const targetPos = element.offsetTop; smoothScroll(targetPos);}节流处理防止滚轮事件频繁触发:
let isScrolling = false;window.addEventListener('wheel', (e) => { if (isScrolling) return; isScrolling = true; e.preventDefault(); // ...滚动逻辑 setTimeout(() => isScrolling = false, duration);});通过以上方法,可以灵活控制网页滚动行为,同时保持平滑的视觉效果。实际开发中需根据项目需求调整参数和边界条件。