JavaScript实现平滑滚动效果:从基础到现代API
本文详解JavaScript实现平滑滚动的两种方案。首先通过getBoundingClientRect获取元素坐标,结合window.scrollX/Y计算绝对位置,使用window.scrollTo实现跳转。随后介绍现代浏览器推荐的behavior: 'smooth'参数,提升用户体验并解决兼容性逻辑问题。
平滑滚动实现概述
本次教程的目标是实现点击按钮时,页面能够平滑滚动至指定的目标区域。

首先,需要获取触发滚动的按钮元素以及目标章节元素的引用。
const btnScrollTo = document.querySelector('.btn--scroll-to');
const section1 = document.querySelector('#section--1');接下来,为按钮绑定点击事件监听器。
btnScrollTo.addEventListener('click', function (e) {
const slcoords = section1.getBoundingClientRect();
});
获取元素坐标与视口信息
getBoundingClientRect() 是 JavaScript 提供的一个方法,用于获取元素相对于浏览器视口(viewport)的位置和尺寸信息。该方法返回一个 DOMRect 对象,其中包含 top、right、bottom、left、width 和 height 等属性。
btnScrollTo.addEventListener('click', function (e) {
const slcoords = section1.getBoundingClientRect();
console.log(slcoords);
});

btnScrollTo.addEventListener('click', function (e) {
const slcoords = section1.getBoundingClientRect();
console.log(slcoords);
console.log(e.target.getBoundingClientRect());
});
通过调用 e.target.getBoundingClientRect(),可以获取触发点击事件的具体元素相对于视口的位置和尺寸数据。
此外,我们还可以获取当前页面滚动条在 X 轴和 Y 轴上的坐标值。
const btnScrollTo = document.querySelector('.btn--scroll-to');
const section1 = document.querySelector('#section--1');
btnScrollTo.addEventListener('click', function (e) {
const slcoords = section1.getBoundingClientRect();
console.log(slcoords);
console.log(e.target.getBoundingClientRect());
console.log('Current scrll (X/Y)', window.scrollX, window.screenY);
});
同时,可以输出视口(viewport)的高度和宽度,即当前可见区域的大小。
console.log(
'height/width viewport',
document.documentElement.clientHeight,
document.documentElement.clientWidth
);
基础滚动定位逻辑
逻辑变得简单:在点击按钮时,直接修改目标章节的坐标参数即可实现跳转。
const btnScrollTo = document.querySelector('.btn--scroll-to');
const section1 = document.querySelector('#section--1');
btnScrollTo.addEventListener('click', function (e) {
const slcoords = section1.getBoundingClientRect();
// console.log(slcoords);
// console.log(e.target.getBoundingClientRect());
// console.log('Current scrll (X/Y)', window.scrollX, window.screenY);
// console.log(
// 'height/width viewport',
// document.documentElement.clientHeight,
// document.documentElement.clientWidth
// );
window.scrollTo(slcoords.left, slcoords.top);
});
处理滚动偏移量
虽然此时可以实现跳转,但细心的开发者会发现,该方案仅在页面处于顶部时有效。如果用户向下滚动了一段距离,章节相对于视口的 X 轴坐标会发生变化,因此必须在计算中加上当前的滚动距离才能准确定位。
const btnScrollTo = document.querySelector('.btn--scroll-to');
const section1 = document.querySelector('#section--1');
btnScrollTo.addEventListener('click', function (e) {
const slcoords = section1.getBoundingClientRect();
// console.log(slcoords);
// console.log(e.target.getBoundingClientRect());
// console.log('Current scrll (X/Y)', window.scrollX, window.screenY);
// console.log(
// 'height/width viewport',
// document.documentElement.clientHeight,
// document.documentElement.clientWidth
// );
window.scrollTo(
slcoords.left + window.scrollX,
slcoords.top + window.scrollY
);
});
修正后,页面在任何滚动位置都能正确跳转,但跳转过程显得生硬。为了实现平滑滚动效果,我们需要进一步优化。
const btnScrollTo = document.querySelector('.btn--scroll-to');
const section1 = document.querySelector('#section--1');
btnScrollTo.addEventListener('click', function (e) {
const slcoords = section1.getBoundingClientRect();
// console.log(slcoords);
// console.log(e.target.getBoundingClientRect());
// console.log('Current scrll (X/Y)', window.scrollX, window.screenY);
// console.log(
// 'height/width viewport',
// document.documentElement.clientHeight,
// document.documentElement.clientWidth
// );
// window.scrollTo(
// slcoords.left + window.scrollX,
// slcoords.top + window.scrollY
// );
window.scrollTo({
left: slcoords.left + window.scrollX,
top: slcoords.top + window.scrollY,
behavior: 'smooth',
});
});
现代浏览器平滑滚动方案
虽然上述方法可以实现平滑滚动,但这些属于较老的操作方式。对于现代浏览器,存在更简洁、现代化的实现方案。
const btnScrollTo = document.querySelector('.btn--scroll-to');
const section1 = document.querySelector('#section--1');
btnScrollTo.addEventListener('click', function (e) {
const slcoords = section1.getBoundingClientRect();
section1.scrollIntoView({ behavior: 'smooth' });
});
采用现代方法可以实现更优雅的平滑滚动,尽管可能存在老旧浏览器不兼容的情况。不过,现代实现方案的底层逻辑依然遵循我们之前推导的步骤。
以上即为 JavaScript 实现平滑滚动效果的完整解析,更多相关技术细节请持续关注本站后续文章。
sigma.js 怎么实现节点点击、拖拽与悬停提示交互
2026-11-05 15:03:27
Matter.js 与 PixiJS/Three.js 集成:分离物理计算与渲染
2026-11-05 13:43:48
主流JS弹幕库选型指南:Danmaku.js等库的功能与体积对比
2026-11-05 09:28:19
JavaScript点击事件监听与交互效果实例
2026-11-05 09:10:19
自定义JS颜色选择器UI样式与交互细节
2026-11-05 09:09:06
