写在最前:文章转自掘金
1. a标签
在 html
中添加 scroll-behavior:smooth;
属性让滚动更顺滑
不过新属性的兼容性不太好
2. scrollTo()
此 api
需要传递 DOM
元素相对于window
的 left
和 top
的距离,此例子仅展示简单demo,只考虑 top
坐标
当然它还有一个 behavior
参数,将其设置为 smooth
后,将会出现滑动效果 步骤如下:
- 计算目标元素距离顶部的距离
- 通过事件触发
代码如下:
const backTop2 = document.getElementById("backTop2")
const TOP = document.getElementById("top")
const y = TOP.offsetTop
const backTop3 = document.getElementById("backTop3")
backTop3.addEventListener("click", function (e) {
window.scrollTo({ top: y, left: 0, behavior: 'smooth' })
})
不过它对iframe
的支持度不够
3. Element.scrollIntoView()
该 api
相较于上一个,节点信息更加的明确,操作方法也更加的简洁,更利于后续的维护
代码如下
const backTop2 = document.getElementById("backTop2")
const TOP = document.getElementById("top")
backTop2.addEventListener("click", function (e) {
TOP.scrollIntoView({ behavior: "smooth" })
})
从效果上来看,该api
和scrollTo
的作用是一致的,但是从代码结构上来说,scrollIntoView
会更加的简洁且在iframe
中表现也很优秀,基本上被用到的频率更高
通用版的js控制回到页面顶部
elementUi
中的 backTop
组件源码,用了requestAnimationFrame
。源码如下:
const cubic = value => Math.pow(value, 3);
const easeInOutCubic = value => value < 0.5
? cubic(value * 2) / 2
: 1 - cubic((1 - value) * 2) / 2;
scrollToTop() {
const el = this.el;// el如果是一个盒子,滚动条会在该盒子内滚动,若没被传参,则为整个页面
const beginTime = Date.now();
const beginValue = el.scrollTop;
const rAF = window.requestAnimationFrame || (func => setTimeout(func, 16));
const frameFunc = () => {
const progress = (Date.now() - beginTime) / 500;
if (progress < 1) {
el.scrollTop = beginValue * (1 - easeInOutCubic(progress));
rAF(frameFunc);
} else {
el.scrollTop = 0;
}
};
rAF(frameFunc);
}
网友评论