开始
最近项目在做列表展示相关的需求,要求有滚动到顶部和底部的快捷按钮,在参考过社区的一些文章后,写下这篇文章,供大家参考!
很多时候我们使用的滚动效果都是类似于锚点那种,一闪而过,给人的体验十分不友好。所以这里介绍一些平滑滚动的方式。
里面有一些相关的知识点,不了解的可以参考这篇文章:链接地址
使用CSS的scroll-behavior
scroll-behavior: auto | smooth | inherit | unset
一般我们使用auto和smooth就可以了,smooth表示滚动很平滑,有过渡效果,auto没有过渡效果,一闪而过。
我们一般回到顶部的话把这个属性设置在html上即可。代码如下
<div id="container" 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型参数
这个是浏览器自带的滚动函数,目前也是属于新功能,可能很多设备及浏览器不支持。这里贴一张MDN的参数解释

这个感觉用起来比CSS还要简单些,给你要滚动的DOM元素绑定这个函数即可
// 滚动到顶部
this.$refs.container.scrollIntoView(true); // vue的语法
// 滚动到底部
this.$refs.container.scrollIntoView(false); // vue的语法
手头设备支持情况
- 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 支持
参考资料
感谢上面这位大佬的文章!