当前遇到了一个这样的业务场景:
当页面滚动距离大于指定距离,显示回到顶部的按钮,否则隐藏按钮;
项目构成:vue-cli + axios
要求:不使用jQuery,使用原生完成这个组件。
首先:MDN中对scroll事件的定义,可以发现其中的关键点element的scroll事件不冒泡, 但是document的defaultView的scroll事件冒泡document.defaultView指的是document的所关联的window对象,主要是在火狐上使用一些window的方法。
然后开始撸代码:
注意
①scroll触发 的频率较高,要使用函数去抖或函数节流
②兼容事件处理
initDom() {
this.listenDocmentScroll();
},
listenDocmentScroll() {
// 使用函数去抖创建执行函数
let fn = this.Plum.debounce(() => {
const scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
// 如果滚动距离大于指定位置,显示图标,否则隐藏图标
if (scrollTop > this.position) {
this.showComponent = true;
} else {
this.showComponent = false;
}
});
// 监听页面滚动事件
this.Plum.addHandler(document, 'scroll', event => {
fn();
}, true);
},
debounce是我封装的函数去抖函数,addHandler是添加兼容事件函数。
总结:刚开始,滚动事件总是没办法触发,所以我以为是vue声明周期的问题,所以就把事件放在mounted中:
mounted() {
this.$nextTick(() => {
this.initDom();
})
},
但是经过反复调试和思考,发现不对,因为document对象是全局的,一致都存在,后来发现是addEventListener的第三个参数不对,应该使用true,即滚动事件是捕获事件而不是冒泡事件。如果是给一个非全局的dom节点添加滚动事件,则可以使用我的代码,在mounted中使用$nextTick,确保dom已经渲染。