一般的网站都有个回到顶部,回到顶部又有多种方法可以实现,
方法1:
在css中添加
html {
scroll-behavior: smooth;
}
然后在回到顶部按钮上加一个a标签,herf属性写顶部标签的id即可。
例如:
<a href="#top">
<div id="one">点我回到顶部</div>
</a>
这样就可以很平滑地回到顶部。不需要用到JavaScript,速度是均匀的,并且不是很快。
方法2:
可以在回到顶部按钮上加一个点击事件:
document.querySelector('回到顶部按钮').onclick = () => { scrollTo(0, 0) }
这样就可以了。只不过这样是瞬间登顶。
function smoothScrollToTop() {
window.scrollTo({
left: 0,
top: 0,
behavior: 'smooth'
})
}
document.getElementById('回到顶部按钮').onclick = smoothScrollToTop;
写成这样就可以达到和方法1一样的效果。
-----------------------------------
方法3:
HTML5有一个api,可以将指定的元素滑动到页面的可视区域中来。
element.scrollIntoView({
behavior: 'auto | smooth | auto(default)',
block: 'start | center | end | nearest (default)'
})
可以设置成点击回到顶部按钮就把页面最上面的那个元素滑动到window的可视区域,元素的顶部与窗口顶部对齐。这样也可以达到目的。
(本质上其实和方法1没什么区别)
function smoothScrollToTop() {
document.getElementById("top").scrollIntoView({ block: "start", behavior: "smooth" })
}
document.getElementById("scrollToTopButton").onclick = smoothScrollToTop;
//top就是最顶部元素地id,scrollToTopButton就是回到顶部按钮地id
-----------------------------------
既然要模仿知乎的回到顶部,自然就需要用到JavaScript了。知乎的回到顶部是变速的,刚开始很快,而后越来越慢,最后一帧非常慢。猜测是每次往前移动一定的比例。
方法4:
可以用scrollTo()函数来模拟,一次性scrollTo(0,0)是瞬间移动,那么多scrollTo()几次,每次往上移动一定的比例就可以做出。
先用 window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop 获取当前页面回到顶部需要滑动的高度。然后使用scrollTo()函数滑动到高一点的某个地方。
屏幕的刷新率一般是60hz,那就每一秒钟调用scrollTo()函数60次吧。经过多次调试,每次往上滑动当前高度的大约15%最接近知乎回到顶部的实际效果。
//setInterval版
function smoothScrollToTop() {
let smoothScrollToTopSetInterval = setInterval(
() => {
let Y_TopValve = (window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop);
if (Y_TopValve > 1) {
scrollTo(0, Math.floor(Y_TopValve * 0.85));
} else {
scrollTo(0, 0);
clearInterval(smoothScrollToTopSetInterval);
}
}, 1000 / 60)
}
document.getElementById('回到顶部按钮').onclick = smoothScrollToTop;
鉴于setInterval经常被诟病,在页面卡死时可能出一些奇怪的问题,那就改造一下,改成setTimeout。
//setTimeout版
function fnScroll() {
let Y_TopValve = (window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop);
if (Y_TopValve > 1) {
scrollTo(0, Math.floor(Y_TopValve * 0.85));
} else {
scrollTo(0, 0);
}
}
function smoothScrollToTop() {
setTimeout(() => {
fnScroll();
let Y_TopValve = (window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop);
if (Y_TopValve > 0) {
smoothScrollToTop();
}
}, 1000 / 60);
}
document.getElementById('回到顶部按钮').onclick = smoothScrollToTop;
但是用setTimeout还是可能会被工头骂,怎么办?
那就只好搬出requestAnimationFrame这个api了。
方法5:
用requestAnimationFrame改造一下方法4,
function smoothScrollToTop() {
let Y_TopValve = (window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop);
if (Y_TopValve > 1) {
window.requestAnimationFrame(smoothScrollToTop);
scrollTo(0, Math.floor(Y_TopValve * 0.85));
} else {
scrollTo(0, 0);
}
}
document.getElementById('回到顶部按钮').onclick = smoothScrollToTop;
完结撒花!