最近做了一个物体可拖拽的需求,由于drag-and-drop在手机上的支持性不是很好,就利用了touch系列事件,改变transform的translate进行位移,从而达到物体跟随手指移动的效果。
但是发现了有以下提示
[Violation] Added non-passive event listener to a scroll-blocking 'touchstart' event.
Consider marking event handler as 'passive' to make the page more responsive.
虽然最终找到了原因是升级taro1.3版本(具体提issue给taro了),但是却让我陷入了思考。
可滑动节点应该是passive
相信大家在使用react开发的时候,如果在touch事件里添加e.preventDefault()
,控制台会报以下的错误:
react-dom.development.js:1458 [Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive
这是由于当监听touch事件时,react默认已经将addEventListener的第三个参数加上了passive:true
,为了可滑动节点在滑动的时候不需要等待js执行的时候就进行滑动的动作,可以看以下touchmove受preventDefault的影响->传送门
从视频里可以看出来,当没有加passive: true时,页面滑动会延迟,甚至出现卡顿。
在可滑动节点上禁止touch的默认行为
因为react默认开启了passive,这让我们无法去通过js层面去禁止可滑动节点touch的默认行为,但是在一些场景下我们禁止掉滑动,通过自己的逻辑来实现“滑动效果”,这时候该怎么做呢?
这里还有一个法宝:
在css属性中,有那么一个东西叫做touch-action。
touch-action 用于设置触摸屏用户如何操纵元素的区域(例如,浏览器内置的缩放功能)。
当touch-action设置为none的时候,浏览器将不能对该节点进行任何的触摸行为,比如说双击图片放大这种行为也可以禁止。所以我们可以设置touch-action: none,代替preventDefault禁止滑动。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。