Unable to preventDefault inside passive event listener due to target being treated as passive.

最近写了个移动端的练手项目,使用了 fastclick ,在同一个 DOM 上连续点击多次的时候,从第二次开始,chrome 的控制台都会出现一条警告,虽然并不影响代码执行,但还是搜索了一番。

Unable to preventDefault inside passive event listener due to target being treated as passive.

我使用了方案二,在全局 CSS 样式中写入 touch-action: none;

先说解决方案:

  • 方案一:
    • 注册处理函数时,用如下方式,明确声明为不是被动的
      window.addEventListener('touchmove', func, { passive: false })
  • 方案二
    • 应用 CSS 属性 touch-action: none; 这样任何触摸事件都不会产生默认行为,但是 touch 事件照样触发。
      touch-action 还有很多选项,详细请参考touch-action

      [注]:未来可能所有的元素的 touchstart touchmove 事件处理函数都会默认为 passive: true

原因:

由于浏览器必须要在执行事件处理函数之后,才能知道有没有掉用过 preventDefault() ,这就导致了浏览器不能及时响应滚动,略有延迟。

所以为了让页面滚动的效果如丝般顺滑,从 chrome56 开始,在 window、document 和 body 上注册的 touchstart 和 touchmove 事件处理函数,会默认为是 passive: true。浏览器忽略 preventDefault() 就可以第一时间滚动了。

举例:
wnidow.addEventListener('touchmove', func) 效果和下面一句一样
wnidow.addEventListener('touchmove', func, { passive: true })

这就导致了一个问题:

如果在以上这 3 个元素的 touchstarttouchmove 事件处理函数中调用 e.preventDefault() ,会被浏览器忽略掉,并不会阻止默认行为。
测试:

body {
  margin: 0;
  height: 2000px;
  background: linear-gradient(to bottom, red, green);
}

// 在 chrome56 中,照样滚动,而且控制台会有提示,blablabla
window.addEventListener('touchmove', e => e.preventDefault())

原文地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值