相关文章推荐
机灵的皮蛋  ·  Postgres包: psycopg2 ...·  6 月前    · 
愉快的电池  ·  embed 标签禁止右键-掘金·  10 月前    · 
有情有义的卤蛋  ·  DataGrid.CancelEdit ...·  1 年前    · 
爱吹牛的稀饭  ·  Android ...·  1 年前    · 
VUE中@scroll失败的真相

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绑定失败的方法有三个:

  1. scroll直接绑定在window的捕获阶段
  2. 使用开发者工具 performance 录制滚动动作,event log 里查看scroll事件的目标元素,然后亲手给这个元素绑定scroll(别忘了它不会冒泡的),如果目标元素是 #document ,只能在 created 里 addEventListener
  3. 如果必须使用@scroll事件,检查以下:
    1. 是否确定了高度(写一行height:100vh,不要随意100%,因为不能保证上一级或者上上一级一定就高度确定),
    2. 是否为overflow:scroll / auto
    3. 然后 performance录制触发scroll检查是不是你想要的元素

关于第一种方法的代码示例

1. created  mounted 里监听
2. 需要的话要移除scroll事件防止当实例不可见还在监听
mounted(){
    window.addEventListener('scroll',this.yyy,true);
methods:{
    yyy(){
        let scrollTop = document.documentElement.scrollTop;