在网页交互中,平滑滚动能让页面跳转更自然,避免突兀的瞬间跳转,提升用户使用体验。实现平滑滚动既可以用浏览器原生提供的API,也可以通过自定义逻辑控制滚动过程,不同方式适配不同的开发需求。

原生API实现平滑滚动
现代浏览器已经原生支持平滑滚动的能力,不需要额外编写复杂的滚动逻辑,最常用的就是window.scrollTo方法配合behavior参数。
使用scrollTo方法时,只需要传入目标位置的横纵坐标,再设置behavior为smooth,就能触发平滑滚动效果,示例代码如下:
// 滚动到页面顶部,平滑过渡
window.scrollTo({
top: 0,
left: 0,
behavior: 'smooth'
});
// 滚动到指定元素位置
const targetElement = document.getElementById('target-section');
if (targetElement) {
// 获取元素距离页面顶部的距离
const targetTop = targetElement.getBoundingClientRect().top + window.pageYOffset;
window.scrollTo({
top: targetTop,
behavior: 'smooth'
});
}除了scrollTo,element.scrollIntoView方法也支持平滑滚动,直接调用目标元素的该方法,设置behavior参数即可,代码更简洁:
const targetElement = document.getElementById('target-section');
if (targetElement) {
targetElement.scrollIntoView({
behavior: 'smooth',
block: 'start', // 对齐方式,start表示元素顶部对齐视口顶部
inline: 'nearest'
});
}自定义平滑滚动逻辑
如果需要控制滚动速度、缓动效果,或者需要兼容不支持原生平滑滚动的旧浏览器,可以自定义滚动逻辑,通过定时器逐步调整滚动位置实现平滑效果。
核心思路是计算当前滚动位置和目标位置的差值,每次定时器触发时移动一小段距离,直到到达目标位置,示例代码如下:
/**
* 自定义平滑滚动函数
* @param {number} targetTop 目标位置的纵坐标
* @param {number} duration 滚动总时长,单位毫秒
*/
function customSmoothScroll(targetTop, duration = 500) {
const startTop = window.pageYOffset; // 起始滚动位置
const distance = targetTop - startTop; // 需要滚动的总距离
let startTime = null;
function step(timestamp) {
if (!startTime) startTime = timestamp;
const progress = timestamp - startTime; // 已经过去的时间
// 计算当前进度,使用缓动函数让滚动更自然,这里用二次缓动
const percent = Math.min(progress / duration, 1);
const easePercent = percent * (2 - percent);
// 计算当前应该滚动到的位置
const currentTop = startTop + distance * easePercent;
window.scrollTo(0, currentTop);
// 如果还没到时间,继续下一帧
if (progress < duration) {
window.requestAnimationFrame(step);
}
}
window.requestAnimationFrame(step);
}
// 使用示例:滚动到id为target-section的元素位置
const targetElement = document.getElementById('target-section');
if (targetElement) {
const targetTop = targetElement.getBoundingClientRect().top + window.pageYOffset;
customSmoothScroll(targetTop, 800); // 800毫秒完成滚动
}两种方式的对比
可以根据项目需求选择合适的实现方式,两者的特点对比如下:
| 实现方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 原生API | 代码简洁,无需额外逻辑,性能由浏览器优化 | 旧浏览器兼容性差,无法自定义滚动速度和缓动效果 | 现代浏览器项目,无特殊定制需求 |
| 自定义逻辑 | 兼容性好,可灵活控制滚动参数,支持自定义缓动效果 | 需要编写额外代码,逻辑相对复杂 | 需要兼容旧浏览器,或有定制滚动效果的需求 |
注意事项
使用平滑滚动时需要注意几个常见问题:
- 原生API的兼容性可以通过caniuse网站查看,如果需要兼容IE等旧浏览器,建议选择自定义实现方式。
- 自定义的滚动逻辑中,尽量使用
requestAnimationFrame而不是setInterval,前者能和浏览器刷新频率同步,滚动效果更流畅,也不会造成不必要的性能消耗。 - 如果页面中有固定定位的导航栏,计算目标元素位置时,需要减去导航栏的高度,避免滚动后元素被导航栏遮挡。
如果项目使用了CSS的scroll-behavior: smooth样式,也可以实现平滑滚动,但这种方式只能通过CSS控制,无法用JavaScript灵活触发,适合全局滚动场景,和JavaScript实现方式可以结合使用。
JavaScript平滑滚动scrollToscroll-behaviorwindow修改时间:2026-06-07 03:27:09