JavaScript实现平滑滚动效果:从基础到现代API

作者:白露时间:2026-10-31 13:53:43浏览:433

本文详解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 实现平滑滚动效果的完整解析,更多相关技术细节请持续关注本站后续文章。

作者最新文章