mousemove报treated as passive错误

150 阅读4分钟

前言

公司有一个很久以前的老项目了,看了下记录发现早就已经不迭代了,受众也不是特别多,但最近新来了个测试同事,不知道怎么就去看这个项目了 然后给我反馈说有报错,我心想不可能啊 所有项目都是解决了一切错误才会发版上线的 怎么会有错误呢 然而我去看了下还真有。有错误不可怕 可怕的是我不知道怎么解决,在我关闭了掘金、博客、百度、AI等几十个页面后,解决了!!!!具体请往下看:

一、mousemove报错

实际业务场景就不往这放了,给大家最精简的复现一下。 可以在编码工具或者浏览器控制台中,写上如下代码:

document.addEventListener('touchmove', function (event) {
   event.preventDefault();
});

我这边为了省事,就直接在浏览器中复现了

image.png 然后将页面调到移动端模式,然后点击页面,滑动鼠标进行拖动 就会发现惊喜:

image.png 错误含义:由于目标被视为被动,因此无法防止被动事件侦听器中的默认值。 详情查看:www.chromestatus.com/features/50…

二、解决问题

碰到这种情况,当然要复制错误然后百度了=。= 解决方式也很简单,我统计了一下,有以下几种:

1.添加{ passive: false }

elem.addEventListener('touchstart', function(e) {
  e.preventDefault();
}, { passive: false });

2.css添加touch-action

html {
    touch-action: none;
}

三、实现及问题来源

问题是很容易的解决了,但为什么之前没这种报错呢,问题是怎么来的,以上解决方法又具体是怎么解决的呢。于是我又开始了漫长的百度与查找=。=

touch-action是移动端一个与手势触摸密切相关的CSS属性,原本源自windows phone手机,微软系,后来被Chrome吸收借鉴,Firefox浏览器跟上,然后Safari也部分支持,目前已经可以说是在移动端可以畅行的CSS属性。

它的关键字值有不少

image.png

  • auto 默认值 没啥说的 由浏览器决定手势操作 例如<meta>元素中的viewport去配置
  • manipulation表示浏览器只允许进行滚动和持续缩放操作,类似双击缩放这种非标准操作就不允许了。(这个属性是不是有点熟悉,很久以前,click事件在移动端有个300ms延时,就是因为避免和手机双击行为发生冲突。当时我们设置touch-action:manipulation来解决这个问题)
  • none表示不进行任何touch相关默认行为。
  • pan-x表示手指头可以左右动。
  • pan-left表示手指头可以往左移动,移动开始后还是可以往右恢复的。
  • pan-right表示手指头可以可以往右移动,移动开始后还是可以往左恢复的。
  • pan-y表示手指头可以上下动。
  • pan-up表示手指头可以往上移动,移动开始后还是可以往下恢复的。
  • pan-down表示手指头可以往下移动,移动开始后还是可以往上恢复的。
  • pan-zoom表示手指头可以用来缩放页面。

用此方法会导致的问题

  1. 它会干掉所有的原生的touch相关行为,但某些业务场景我们是需要这些行为的。
  2. safari浏览器不支持=。=

passive:false又是怎么解决的呢

其实就是给addEventListener的第三个参数传递了这个属性,相当于我们告诉了浏览器,我现在操作不是被动的,我就是要这样做,浏览器也不好拒绝我们,就解决了问题了。

来源

那为什么之前项目上线的时候没报错呢,经过一系列的查找 结果如下:

当浏览器执行事件处理函数的时候,要检查一下是否进行了默认事件的取消,这就导致了浏览器不能及时响应滚动,略有延迟。google浏览器为了最快速的相应touch,scroll事件,从 chrome56 开始,触摸事件,滑动事件,事件处理函数,会默认 passive: true,忽略 preventDefault()

四、结束

今天又是成长的一天!!! (万恶的测试,肯定比我早秃头!!!!)