div overflow scroll_VUE中@scroll失败的真相

v2-9a94b0fc4e938b418f6065576ea90b71_1440w.jpg?source=172ae18b
vue不能老实的 @scroll真的是一大心病,今天就来去了这颗心病

先看MDN上关于scroll事件冒泡的描述:element的scroll事件不冒泡, 但是document的defaultView的scroll事件冒泡,

意思大概是监听的目标元素(element)是一个div的话,scroll事件不会冒泡到上一级,而document.defaultView(在浏览器上就是window)会冒泡(这里window已经是最顶级了,冒泡并没有卵用)

举个例子:

文档结构例如:

html > body > wrapper > box

在上面四个连加window,一共五个都绑定 scroll事件,同时触发捕获和冒泡阶段,测试结果事件触发顺序为 :

v2-d8592cc893e0cd076b6805c36198f3b7_b.jpg

示例地址

可见:在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. 

关于自定义组件: 组件根组件监听事件

<my-component @scroll.native="handleScroll">


关于移动端的滚动

1. 监听 @scroll.passive (.passive 使得滚动行为立即触发)

2. 监听 @touchmove

所以:问题不是 vue 不能使用@scroll,而是即使是普通的页面不满足scroll的要求也一样不能执行回调,人家只是默默不说话,看着你没头没脑自个滚的开心。。

关于获取滚动距离的问题:

获取滚动距离 document.body.scrollTop 在 chrome 存在兼容性问题,可用以下三个代替:

  1. window.pageYOffset
  2. window.scrollY
  3. document.documentElement.scrollTop

Appendix:

mdn中的scroll

segmentfault 提出相关解决方法

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值