VUE回到顶部组件,使用requestAnimationFrame
这篇文章是18年就写的了,那时候element-ui还没有回到顶部组件,我就弄了一个,现在官网已经有了。想直接使用的话可以使用官网上的,但是官网的是使用setInterval写的,我就顺便改一下这篇文章,使用requestAnimationFrame弄一个
·
背景
这篇文章是18年就写的了,那时候element-ui还没有回到顶部组件,我就弄了一个,现在官网已经有了。想直接使用的话可以使用官网上的,但是官网的是使用setInterval写的,我就顺便改一下这篇文章,使用requestAnimationFrame弄一个。
开发
1. HTML部分
code:
<template>
<div title="回到顶部" class="comp-to-top" @click="scrollToTop" v-show="toTopShow">TOP</div>
</template>
2. CSS部分
code:
<style scoped lang="scss">
.comp-to-top {
background-color: #4aa557;
position: fixed;
right: 20px;
bottom: 30px;
width: 40px;
height: 40px;
border-radius: 20px;
line-height: 40px;
text-align: center;
color: #fff;
font-weight: 800;
cursor: pointer;
transition: 0.3s;
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.5);
opacity: 0.5;
z-index: 100;
&:hover {
opacity: 1;
}
}
</style>
这也没啥说的,自己觉得好看就行。
现在大概是这个样子:
3. JavaScript部分
这里是重点了,主要是监听两个事件:
屏幕滚动事件
回到顶部按钮的点击事件
屏幕滚动事件
code:
mounted() {
window.addEventListener("scroll", this.handleScroll, true);
},
destroyed() {
window.addEventListener("scroll", this.handleScroll, true);
},
这里有两个注意事项:
注意是将事件绑定在window上,监听整个文档的滚动,也可以绑在document或者document.body上
需要在元素加载之后再监听滚动事件
需要将addEventListener的第三个参数设置为true,即取消冒泡,要不然会绑定不成功
code:
handleScroll() {
this.dom = document.querySelector(this.scrollDom);
this.scrollTop = this.dom.scrollTop;
if (this.scrollTop > 100) {
this.toTopShow = true;
} else {
this.toTopShow = false;
}
},
这里需要注意的地方是:
- 一开始不必将回到顶部按钮显示出来,等用户将页面往下滑动一段距离(100)之后再显示回到顶部按钮,这样更加符合用户的操作习惯
this.scrollDom
是使用组件的时候传进来的参数,表示触发滚动的对象
回到顶部按钮的点击事件
code:
scrollToTop() {
let timer = null;
let _this = this;
//动画,使用requestAnimationFrame代替setInterval
cancelAnimationFrame(timer);
timer = requestAnimationFrame(function fn() {
if (_this.scrollTop > 1000) {
_this.scrollTop -= 1000;
_this.dom.scrollTop = _this.scrollTop;
timer = requestAnimationFrame(fn);
} else if (_this.scrollTop > 100 && _this.scrollTop <= 1000) {
_this.scrollTop -= 100;
_this.dom.scrollTop = _this.scrollTop;
timer = requestAnimationFrame(fn);
} else if (_this.scrollTop > 10 && _this.scrollTop <= 100) {
_this.scrollTop -= 10;
_this.dom.scrollTop = _this.scrollTop;
timer = requestAnimationFrame(fn);
} else if (_this.scrollTop > 0 && _this.scrollTop <= 10) {
_this.scrollTop -= 2;
_this.dom.scrollTop = _this.scrollTop;
timer = requestAnimationFrame(fn);
} else {
cancelAnimationFrame(timer);
_this.toTopShow = false;
}
});
}
这里需要主要几点:
使用requestAnimationFrame,优点就不必多说了
正常情况下回到顶部的速度是由快变慢的,这样看起来更加符合用户的使用习惯,而且效果也更加好看
将距离顶部的距离划分为四个部分,每个部分的速度都不一样
4. 调用
全部页面调用
- 操作App.vue
- 添加JavaScript代码
<script>
import ScrollTop from './components/ScrollTop.vue'
export default {
components: {
'scroll-top':ScrollTop,
}
}
</script>
- 页面中引用
<scroll-top :scrollDom=".content-container"></scroll-top>
大功告成!
单个页面调用
操作需要调用该组件的页面文件即可,方法同上。
5. 全部代码
<template>
<div title="回到顶部" class="comp-to-top" @click="scrollToTop" v-show="toTopShow">TOP</div>
</template>
<script>
export default {
props: {
scrollDom: {
type: String,
default: ".content-container"
}
},
data() {
return {
dom: null,
toTopShow: false,
scrollTop: ""
};
},
mounted() {
this.$nextTick(() => {
window.addEventListener("scroll", this.handleScroll, true);
});
},
destroyed() {
window.addEventListener("scroll", this.handleScroll, true);
},
methods: {
handleScroll() {
this.dom = document.querySelector(this.scrollDom);
this.scrollTop = this.dom.scrollTop;
if (this.scrollTop > 100) {
this.toTopShow = true;
} else {
this.toTopShow = false;
}
},
scrollToTop() {
let timer = null;
let _this = this;
//动画,使用requestAnimationFrame代替setInterval
cancelAnimationFrame(timer);
timer = requestAnimationFrame(function fn() {
if (_this.scrollTop > 1000) {
_this.scrollTop -= 1000;
_this.dom.scrollTop = _this.scrollTop;
timer = requestAnimationFrame(fn);
} else if (_this.scrollTop > 100 && _this.scrollTop <= 1000) {
_this.scrollTop -= 100;
_this.dom.scrollTop = _this.scrollTop;
timer = requestAnimationFrame(fn);
} else if (_this.scrollTop > 10 && _this.scrollTop <= 100) {
_this.scrollTop -= 10;
_this.dom.scrollTop = _this.scrollTop;
timer = requestAnimationFrame(fn);
} else if (_this.scrollTop > 0 && _this.scrollTop <= 10) {
_this.scrollTop -= 2;
_this.dom.scrollTop = _this.scrollTop;
timer = requestAnimationFrame(fn);
} else {
cancelAnimationFrame(timer);
_this.toTopShow = false;
}
});
}
}
};
</script>
<style scoped lang="scss">
.comp-to-top {
background-color: #4aa557;
position: fixed;
right: 20px;
bottom: 30px;
width: 40px;
height: 40px;
border-radius: 20px;
line-height: 40px;
text-align: center;
color: #fff;
font-weight: 800;
cursor: pointer;
transition: 0.3s;
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.5);
opacity: 0.5;
z-index: 100;
&:hover {
opacity: 1;
}
}
</style>
更多推荐
已为社区贡献3条内容
所有评论(0)