手动实现,原生“回到顶部”的功能,不使用插件,可以减少加载外部无用的功能加载。
- 使用
visibility去控制显示。使用display:none隐藏 DOM 元素,会同时导致重排和重绘;使用visibility:hidden只会造成重绘,因为没有布局和位置的改变,所以不发生重排,对页面性能开销比较小
scroll() {
const targetEle = document.querySelector(".backtop[css-backtop]");
if (document.documentElement.scrollTop >= 200) {
targetEle.style.visibility = "visible";
} else {
targetEle.style.visibility = "hidden";
}
}
throttle节流函数,避免一定时间内重复触发
throttle(fn, wait) {
let inThrottle, lastFn, lastTime;
return function () {
const context = this,
args = arguments;
if (!inThrottle) {
fn.apply(context, args);
lastTime = Date.now();
inThrottle = true;
} else {
clearTimeout(lastFn);
lastFn = setTimeout(function () {
if (Date.now() - lastTime >= wait) {
fn.apply(context, args);
lastTime = Date.now();
}
}, Math.max(wait - (Date.now() - lastTime), 0));
}
};
}
requestAnimationFrame和setTimeout去实现一个重复向上滚动的过程,而不是一次性滚到顶部
scrollToTop() {
const el = document.documentElement;
const beginTime = Date.now();
const beginValue = el.scrollTop;
const rAF =
window.requestAnimationFrame || ((func) => setTimeout(func, 16));
const cubic = (value) => Math.pow(value, 3);
const easeInOutCubic = (value) =>
value < 0.5 ? cubic(value * 2) / 2 : 1 - cubic((1 - value) * 2) / 2;
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);
},
- 设置对应点击和滚动事件,最终调用如下方法
loadBacktop() {
const targetEle = document.querySelector(".backtop[css-backtop]");
targetEle.addEventListener("click", backtopObj.scrollToTop);
const throttledScrollHandler = util.throttle(backtopObj.scroll, 300);
window.addEventListener("scroll", throttledScrollHandler);
},
- 页面样式设置
<div class="backtop" css-backtop="" style="visibility:hidden"><img data-v-09f6b925=""
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAtCAYAAADV2ImkAAAAAXNSR0IArs4c6QAAA3NJREFUaEPtmUvIVVUUx3//QgdJ+KKRgoFFiIIPciSKmCkEaha+EsRHE0HUkMRIsVTEF2pJgQ8CwUdvVBz4QEWEUHxMxIkYRTTSgdLAicpf9sf55H733nP2Puc7OOmu2eX811q/vc7a+6zNFTWa7SnAWmA88AjYL2lHjSlQXcFszwBOtYm3S9LndeWpBdj2GOAG8GoO2F5Jn9UB3Wtg20uAHxJgdktak6ArlPQK2PYGYFMJiC2Sgk9lqwxsez2wuULmrZK+rODX5VIJ2PZG4KuqSYOvpK+r+JcGLtGzMZ6Nksq0U/kK254KnI+RlHi+TdIXJfTpLWF7OfB9meCJ2lI9ndQStlcBexMBqsiS2yMKbHsZcKgKRUmfTZLCZq5+DtteDeyJBanx+VpJO4vi5VbY9mzg9wSYP4ETQN5XzMA3wAhgekK8NZJ25+naAtseC9xKCP4f8BbwOhDA82yUpDu2LwGTE+LmVroFOBsRfwYGRwI/BSZKump7DhB88myhpGO2+2YLG5oAvUrSt826HsC2FwGHE4I9A96TdDlobX8M/FrgN0dS13Pbw4F7CTmCZIWk7xq1L4BtLwSOJAaaJOlKt9b2R8BvBb5zJf3SoJ8InAQGJuRbKWlft64L2PasbOMk+DNV0oVGYQLwfEk/NfmMAq4BryUkXSyp683L9hDgH+CViONjYGYzbLbgWIVftEQT9GjgOtAnATq04MUAfBaYFnF4km2wUJEWS6hwW+Bsse8DR4E3Igx3Jb0TgMM5GbNpknKHnoRNN09S7iliO5zRtwuuWIHvsaR+Afh+ZHUzJJ0uWlFChQuBs0qPA24W5HkqqU8ADkNNGG7aWTRRlix2DrdsupzW+jAbsoa1eb5d0roAPAA4AISk3fYQWCopfHKjZns+cLxAmAScLb5/thHfboi3T9LK8LvxHB4JfJJ9ic5J+jdKmglszwN+rAM4gx4EfJDxPZB0pjt2dLxMga4buChnBzinOsk9HHuj/9sKx6a1pOMxVt0ep0SKOE/T2y9dmdx1tUSnwnlV71Q4pzKdTVdmo7ZoO6dEQfnq2nRzgR6XzKacs1NH1dirflnAsyS1+0ssxtfyvC7gBcCxuubhlzFevgn8VZDoXUlF97XkStdS4eyWcBD4tE3mPyRNSCaKCOsEDhfHv9vkGy8p/Etaiz0HnJdhPQFhR0AAAAAASUVORK5CYII="
width="22px" height="23px" alt=""></div>
<style>
.backtop[css-backtop] {
background-color: rgba(0, 0, 0, .5);
right: 10px;
bottom: 100px;
position: fixed;
width: 40px;
height: 40px;
border-radius: 50%;
color: #409eff;
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
box-shadow: 0 0 6px rgb(0 0 0 / 12%);
cursor: pointer;
z-index: 5;
}
</style>
- 最终实现效果