平滑滚动到顶部或底部的几种方案

发布于 2023-09-04 13:02:58 字数 3283 浏览 34 评论 0

最近项目在做列表展示相关的需求,要求有滚动到顶部和底部的快捷按钮,在参考过社区的一些文章后,写下这篇文章,供大家参考:很多时候我们使用的滚动效果都是类似于锚点那种,一闪而过,给人的体验十分不友好。所以这里介绍一些平滑滚动的方式。

使用 CSS 的 scroll-behavior

scroll-behavior: auto | smooth | inherit | unset

一般我们使用 auto 和 smooth 就可以了,smooth 表示滚动很平滑,有过渡效果,auto 没有过渡效果,一闪而过。我们一般回到顶部的话把这个属性设置在 html 上即可。代码如下

<div class="box">
  <p>Hello, Backtotop</p>
  <br/>
  <p>Hello, Backtotop</p>
  <br/>
  <p>Hello, Backtotop</p>
  <br/>
  <p>Hello, Backtotop</p>
  <br/>
  /* 省略部分代码 */
</div>
<a href="#container" class="backto-top-btn">回到顶部按钮</a>

css 样式代码:

html {
  scroll-behavior: smooth;
}

注意:上面那个我用的 a 标检加 id,这种可能不太好,因为 a 标签的默认行为会给地址加一个 hash,这对 vue 的路由使用 hash 模式来说会出现问题。

更简单的方法

回到顶部

上面 a 标签的默认行为会出问题,我们可以使用更简便的方式来实现,首先在你的页面的给 html 加一个样式:

html {
  scroll-behavior: smooth;
}

给你的回到顶部的按钮绑定一个事件,比如点击事件,里面加入我们平时使用的回到顶部的代码

window.scrollTo(0, 0);

然后这样的话,只要你的设备及浏览器支持这个 CSS 属性的话,那么也会有过渡平滑的效果。

回到底部

回到底部可以这样操作,我们计算出 DOM 元素的高度,减去我们视窗的高度,那么就是底部了

window.scrollTo(0, document.documentElement.scrollHeight - window.innerHeight);

手头设备支持情况

  • iOS 13.3 Safari 不支持 smooth
  • iOS 11.4.1 Safari 不支持 smooth
  • Galaxy S9 Android 9.0 自带浏览器 支持 smooth
  • Chrome 79 支持 smooth

使用 JS 的 Element.scrollIntoView()

element.scrollIntoView(); // 等同于 element.scrollIntoView(true) 
element.scrollIntoView(alignToTop); // Boolean 型参数 
element.scrollIntoView(scrollIntoViewOptions); // Object 型参数

这个是浏览器自带的滚动函数,目前也是属于新功能,可能很多设备及浏览器不支持。这个感觉用起来比 CSS 还要简单些,给你要滚动的 DOM 元素绑定这个函数即可

// 滚动到顶部
this.$refs.container.scrollIntoView(true);

// 滚动到底部
this.$refs.container.scrollIntoView(false);

手头设备支持情况

  • iOS 13.3 Safari 不支持 smooth
  • iOS 11.4.1 Safari 不支持 smooth
  • Galaxy S9 Android 9.0 自带浏览器 支持 smooth
  • Chrome 79 支持 smooth

多设备支持的缓冲方案

// 封装一个回到底部或者顶部的函数
scrollToTop(position) {
  // 使用 requestAnimationFrame,如果没有则使用 setTimeOut
  if(!window.requestAnimationFrame) {
    window.requestAnimationFrame = function(callback) {
      return setTimeout(callback, 20)
    }
  }

  // 获取当前元素滚动的距离
  let scrollTopDistance = document.documentElement.scrollTop || document.body.scrollTop;

  function smoothScroll() {
    // 如果你要滚到顶部,那么 position 传过来的就是 0,下面这个 distance 肯定就是负值。
    let distance = position - scrollTopDistance;
    // 每次滚动的距离要不一样,制造一个缓冲效果
    scrollTopDistance = scrollTopDistance + distance / 5;
    // 判断条件
    if(Math.abs(distance) < 1) {
      window.scrollTo(0, position);
    }else {
      window.scrollTo(0, scrollTopDistance);
      requestAnimationFrame(smoothScroll);
    }
  }

  smoothScroll();

调用这个函数

// 回到顶部
scrollToTop(0);

// 滚到底部
scrollToTop(document.documentElement.scrollHeight - window.innerHeight);

手头设备支持情况

  • iOS 13.3 Safari 支持
  • iOS 11.4.1 Safari 支持
  • Galaxy S9 Android 9.0 自带浏览器 支持
  • Chrome 79 支持

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

风月客

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

qq_E2Iff7

文章 0 评论 0

Archangel

文章 0 评论 0

freedog

文章 0 评论 0

Hunk

文章 0 评论 0

18819270189

文章 0 评论 0

wenkai

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文