从新版浏览器报错看touch事件和touch-event属性

本文介绍了浏览器在处理touch事件时遇到的`Unable to preventDefault inside passive event listener`报错,分析了原因及Chrome为优化滚动体验所做的改变。针对此问题,提出了两种解决方案:设置事件处理函数为非被动模式或使用CSS属性`touch-action`。同时,文章提到了`touch-action`在移动端的兼容性问题,建议在处理此类问题时谨慎使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Unable to preventDefault inside passive event listener

浏览器报错:

Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/5093566007214080

根据浏览器报错给的链接,找到这篇文章,有了详细解释。Making touch scrolling fast by default

简而言之:

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

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

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

这就导致了一个问题:

如果在以上这 3个元素的 touchstarttouchmove 事件处理函数中调用 e.preventDefault() ,会被浏览器忽略掉,并不会阻止默认行为,且控制台会报出以上错误信息。

那么如何解决这个问题呢?不让控制台提示,而且preventDefault()有效果呢?
两个方案:
1、注册处理函数时,用如下方式,明确声明为不是被动的

window.addEventListener('touchmove', func, { passive: false })//不推荐,因为需要检测USER AGENT是否支持EventListenrOption.(https://github.com/WICG/EventListenerOptions)

2、应用 CSS 属性 touch-action

 touch-action: none;// 这样任何触摸事件都不会产生默认行为,但是 touch 事件照样触发。
 使得图片在处置方向也可以滑动和缩放。

根据谷歌的官方说法,谷歌不推荐在网页的touchstarttouchmove事件处理函数中调用preventDefault()但在移动端 safari 中仍需要),而是通过应用CSS属性touch-action阻止滚动和缩放,所以这一特性将来可能会应用到所有元素中。而touchend事件处理函数中可以调用preventDefault().

但实际情况可能并非如此。

关于touch-action

首先了解一下 touch-action 属性

CSS属性 touch-action 用于设置触摸屏用户如何操纵元素的区域(例如,浏览器内置的缩放功能)。

/* Keyword values */
touch-action: auto;//由浏览器处理触控事件
touch-action: none;//不进行任何操作

//启用单指水平平移手势。可以与 pan-y 、pan-up、pan-down 和/或 pinch-zoom 组合使用。
touch-action: pan-x;
//启用单指垂直方向水平平移。参考 pan-x
touch-action: pan-y;

//启用以指定方向滚动开始的单指手势。 一旦滚动开始,方向可能仍然相反。 请注意,滚动“向上”(pan-up)意味着用户正在将其手指向下拖动到屏幕表面上,同样 pan-left 表示用户将其手指向右拖动。 多个方向可以组合,除非有更简单的表示(例如,“pan-left pan-right”无效,因为“pan-x”更简单,而“pan-left pan-down”有效)。
touch-action: pan-left;
touch-action: pan-right;
touch-action: pan-up;
touch-action: pan-down;

//启用多手指平移和缩放页面。 这可以与任何平移值组合。
touch-action: pinch-zoom;

//浏览器只允许进行滚动和持续缩放操作。任何其它被auto值支持的行为不被支持。启用平移和缩小缩放手势,但禁用其他非标准手势,例如双击以进行缩放。 禁用双击可缩放功能可减少浏览器在用户点击屏幕时延迟生成点击事件的需要。 这是“pan-x pan-y pinch-zoom”(为了兼容性本身仍然有效)的别名。
touch-action: manipulation;

/* Global values */
touch-action: inherit;
touch-action: initial;
touch-action: unset;

更详细的touch-action说明请看 这里

需要注意避免的坑是 touch-action移动端的问题:
1.iOS 移动端不支持该属性。
2.在安卓手机中如果为了避免chrome报错而在全局设置touch-action:none属性,会禁止掉所有的触摸操作行为,导致页面不能滑动。

基于以上两个原因,即使谷歌官方推荐使用touch-action:none来处理这个报错,最终解决方案还是选择用js在注册事件处理函数时传入{passive:false}

window.addEventListener('touchmove', func, { passive: false })

最后,由于报错是由第三方库引发,修改第三方库的js源码过于繁琐,直接升级了第三方库解决了这个问题(此处应有表情)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值