VUE中@scroll失败的真相
vue不能老实的 @scroll真的是一大心病,今天就来去了这颗心病
先看MDN上关于scroll事件冒泡的描述:element的scroll事件不冒泡, 但是document的defaultView的scroll事件冒泡,
意思大概是监听的目标元素(element)是一个div的话,scroll事件不会冒泡到上一级,而document.defaultView(在浏览器上就是window)会冒泡(这里window已经是最顶级了,冒泡并没有卵用)
举个例子:
文档结构例如:
html > body > wrapper > box
在上面四个连加window,一共五个都绑定 scroll事件,同时触发捕获和冒泡阶段,测试结果事件触发顺序为 :
可见:在box之后就不再冒泡了,wrapper的scroll并未执行。
ps: box 只有在 overflow:scroll / auto且确定了高度 时 才会被window捕获到。
所以 解决scroll绑定失败的方法有三个:
- scroll直接绑定在window的捕获阶段
- 使用开发者工具 performance 录制滚动动作,event log 里查看scroll事件的目标元素,然后亲手给这个元素绑定scroll(别忘了它不会冒泡的),如果目标元素是 #document ,只能在 created 里 addEventListener
- 如果必须使用@scroll事件,检查以下:
- 是否确定了高度(写一行height:100vh,不要随意100%,因为不能保证上一级或者上上一级一定就高度确定),
- 是否为overflow:scroll / auto
- 然后 performance录制触发scroll检查是不是你想要的元素
关于第一种方法的代码示例
1. created 或 mounted 里监听
2. 需要的话要移除scroll事件,防止当实例不可见还在监听
mounted(){
window.addEventListener('scroll',this.yyy,true);
methods:{
yyy(){
let scrollTop = document.documentElement.scrollTop;