前言
公司有一个很久以前的老项目了,看了下记录发现早就已经不迭代了,受众也不是特别多,但最近新来了个测试同事,不知道怎么就去看这个项目了 然后给我反馈说有报错,我心想不可能啊 所有项目都是解决了一切错误才会发版上线的 怎么会有错误呢 然而我去看了下还真有。有错误不可怕 可怕的是我不知道怎么解决,在我关闭了掘金、博客、百度、AI等几十个页面后,解决了!!!!具体请往下看:
一、mousemove报错
实际业务场景就不往这放了,给大家最精简的复现一下。 可以在编码工具或者浏览器控制台中,写上如下代码:
document.addEventListener('touchmove', function (event) {
event.preventDefault();
});
我这边为了省事,就直接在浏览器中复现了
然后将页面调到移动端模式,然后点击页面,滑动鼠标进行拖动 就会发现惊喜:
错误含义:由于目标被视为被动,因此无法防止被动事件侦听器中的默认值。
详情查看: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属性。
它的关键字值有不少
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表示手指头可以用来缩放页面。
用此方法会导致的问题
- 它会干掉所有的原生的touch相关行为,但某些业务场景我们是需要这些行为的。
- safari浏览器不支持=。=
passive:false又是怎么解决的呢
其实就是给addEventListener的第三个参数传递了这个属性,相当于我们告诉了浏览器,我现在操作不是被动的,我就是要这样做,浏览器也不好拒绝我们,就解决了问题了。
来源
那为什么之前项目上线的时候没报错呢,经过一系列的查找 结果如下:
当浏览器执行事件处理函数的时候,要检查一下是否进行了默认事件的取消,这就导致了浏览器不能及时响应滚动,略有延迟。google浏览器为了最快速的相应touch,scroll事件,从 chrome56 开始,触摸事件,滑动事件,事件处理函数,会默认 passive: true,忽略 preventDefault()
四、结束
今天又是成长的一天!!! (万恶的测试,肯定比我早秃头!!!!)