前言
我们在做移动端端的拖动效果时(touchstart,touchmove,touchend),有的时候会遇到一个如下错误:
Unable to preventDefault inside passive event listener due to target being treated as passive.
百度后,查到了原因:
由于浏览器必须要在执行事件处理函数之后,才能知道有没有掉用过 preventDefault() ,这就导致了浏览器不能及时响应滚动,略有延迟。
所以为了让页面滚动的效果如丝般顺滑,从 chrome56 开始,在 window、document 和 body 上注册的 touchstart 和 touchmove 事件处理函数,会默认为是 passive: true。浏览器忽略 preventDefault() 就可以第一时间滚动了。
举例:
wnidow.addEventListener('touchmove', func) 效果和下面一句一样55
wnidow.addEventListener('touchmove', func, { passive: true })
解决方法:
1、注册处理函数时,用如下方式,明确声明为不是被动的。
window.addEventListener('touchmove', func, { passive: false })
2、 为容器设置css属性[touch-action]去除滑动时默认现象产生,但不影响事件触发
touch-action: none;
e.preventDefault()
preventDefault()是阻止默认事件的方法,一般来说,事件传递过程为:用户操作-》方法捕捉-》浏览器默认行为。例如标签a,我们绑定了一个click事件,那么我们点击后,会执行click方法,然后会进行跳转。但是我们可以在click方法里写preventDefault()来阻止跳转动作。
但是touch事件不太一样,因为你在移动的时候,浏览器也要利用touch事件进行移动(例如页面滚动等),如果每次都去判断用户是否调用preventDefault()方法就很麻烦了,所以touch事件默认先执行浏览器行为,用户操作-》浏览器默认行为-》方法捕捉。因此这个你的preventDefault()无法阻止默认行为。
因此,touch事件在默认的情况下passive为true,就是被动的意思,如果想要先执行绑定操作,就要配置passive为false。
obj.addEventListener('touchstart',function(e){
//.....
e.preventDefault();
},{passive:false});
touch-action
当然,还有一个css属性可以控制:touch-action:none,这样的话,浏览器就不会执行默认的touch动作。不过注意,这个属性千万不要乱用,否则可能导致无法正常滚动。
注意,touch事件中只有touchstart和touchmove才具有此特性,touchend等其他touch属性是没有的。
值 auto
当触控事件发生在元素上时,不进行任何操作。
值 none
当触控事件发生在元素上时,不进行任何操作。
值 pan-x
启用单指水平平移手势。可以与 pan-y 、pan-up、pan-down 和/或 pinch-zoom 组合使用。
值 pan-y
启用单指垂直平移手势。可以与 pan-x 、pan-left 、pan-right 和/或 pinch-zoom 组合使用。
值 manipulation
浏览器只允许进行滚动和持续缩放操作。任何其它被auto值支持的行为不被支持。启用平移和缩小缩放手势,但禁用其他非标准手势,例如双击以进行缩放。 禁用双击可缩放功能可减少浏览器在用户点击屏幕时延迟生成点击事件的需要。 这是“pan-x pan-y pinch-zoom”(为了兼容性本身仍然有效)的别名。
值 pan-left, pan-right,pan-up,pan-down
启用以指定方向滚动开始的单指手势。 一旦滚动开始,方向可能仍然相反。 请注意,滚动“向上”(pan-up)意味着用户正在将其手指向下拖动到屏幕表面上,同样 pan-left 表示用户将其手指向右拖动。 多个方向可以组合,除非有更简单的表示(例如,“pan-left pan-right”无效,因为“pan-x”更简单,而“pan-left pan-down”有效)。
值 pinch-zoom
启用多手指平移和缩放页面。 这可以与任何平移值组合。
示例 最常见的用法是禁用元素(及其不可滚动的后代)上的所有手势,以使用自己提供的拖放和缩放行为(如地图或游戏表面)
另一种常见的模式是使用指针事件处理水平平移的图像轮播,但不想干扰网页的垂直滚动或缩放。
触摸动作也经常用于完全解决由支持双击缩放手势引起的点击事件的延迟。
网友评论