女王控的博客

CSS scroll-behavior和JS scrollIntoView让页面滚动平滑

假设页面中有下面这一段 HTML:

html 复制代码
<a href="#" rel="internal">返回顶部</a>

点击“返回顶部”这个文字链接的时候,页面就会“唰”地瞬间定位到浏览器顶部。

浏览器已经开始支持原生平滑滚动定位,CSS scroll-behavior 属性和 JS scrollIntoView()方法都可以。

CSS scroll-behavior 与平滑滚动

scroll-behavior:smooth 写在滚动容器元素上,可以让容器(非鼠标手势触发)的滚动变得平滑。

语法

css 复制代码
scroll-behavior: auto;
scroll-behavior: smooth;

初始值是’auto’。

凡是需要滚动的地方都加一句 scroll-behavior:smooth 就好了!

举个例子,在 PC 浏览器中,网页默认滚动是在<html>标签上的,移动端大多数在<body>标签上,于是,我加上这么一句:

css 复制代码
html,
body {
  scroll-behavior: smooth;
}

JS scrollIntoView 与平滑滚动

DOM 元素的 scrollIntoView()方法是一个 IE6 浏览器也支持的原生 JS API,可以让元素进入视区,通过触发滚动容器的定位实现。

随着 Chrome 和 Firefox 浏览器开始支持 CSS scroll-behavior 属性,顺便对 scrollIntoView()方法进行了升级,使支持更多参数,其中一个参数就是可以使滚动平滑。

语法如下:

js 复制代码
target.scrollIntoView({
  behavior: 'smooth'
});

我们随便打开一个有链接的页面,把首个链接滚动到屏幕外,然后控制台输入类似下面代码,我们就可以看到页面平滑滚动定位了:

js 复制代码
document.links[0].scrollIntoView({
  behavior: 'smooth'
});

其他

  • scrollIntoView()升级后的方法,除了支持’behavior’,还有’block’和’inline’等参数,有兴趣可以参阅 MDN 相关文档。

  • 如果我们的网页已经通过 CSS 设置了 scroll-behavior:smooth 声明,则我们直接执行 target.scrollIntoView()方法就会有平滑滚动,无需再额外设置 behavior 参数。

    js 复制代码
    document.forms[0].scrollIntoView();

JS 平滑滚动向下兼容处理

JS 实现平滑滚动并不难,jQuery 中 animate()方法:

js 复制代码
scrollContainer.animate({
  scrollTop: 0
});

或者使用 requestAnimationFrame API 这类原生 JS 也能实现。例如下面这个我速写的个方法:

js 复制代码
/**
 @description 页面垂直平滑滚动到指定滚动高度
 @author zhangxinxu(.com)
*/
var scrollSmoothTo = function(position) {
  if (!window.requestAnimationFrame) {
    window.requestAnimationFrame = function(callback, element) {
      return setTimeout(callback, 17);
    };
  }
  // 当前滚动高度
  var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  // 滚动step方法
  var step = function() {
    // 距离目标滚动距离
    var distance = position - scrollTop;
    // 目标滚动位置
    scrollTop = scrollTop + distance / 5;
    if (Math.abs(distance) < 1) {
      window.scrollTo(0, position);
    } else {
      window.scrollTo(0, scrollTop);
      requestAnimationFrame(step);
    }
  };
  step();
};

使用的是缓动动画 JS 小算法,滚动先快后慢。

使用如下,例如我们希望网页平滑滚动到顶部,直接:

js 复制代码
scrollSmoothTo(0);

难的是如何支持平滑滚动的浏览器原生处理,不支持的浏览器还是使用老的 JS 方法处理。

js 复制代码
if (typeof window.getComputedStyle(document.body).scrollBehavior == 'undefined') {
  // 传统的JS平滑滚动处理代码...
}

评论

阅读上一篇

SVG/Canvas中nonzero和evenodd填充规则
2020-01-14 16:48:52

阅读下一篇

CSS世界的层叠规则
2020-01-10 10:19:55
0%