我正在尝试做类似于嵌入式Google地图的操作。我的组件应忽略单点触摸(允许用户滚动页面),并在其自身外部捏合(允许用户缩放页面),但应对双键触摸做出反应(允许用户在组件内部导航),并在这种情况下禁止任何默认操作。
如何防止触摸事件的默认处理,仅在用户用两只手指与我的组件进行交互的情况下?
我尝试过的
我尝试捕获onTouchStart,onTouchMove和onTouchEnd。事实证明,在FF Android上,对部件进行捏合时触发的第一个事件是单击onTouchStart,然后触摸onTouchStart两次,然后是onTouchMove。但是,调用event.preventDefault()或event.stopPropagation()in onTouchMove处理程序并不会(总是)停止页面缩放/滚动。防止在第一个呼叫中发生事件升级onTouchStart 确实有帮助 -不幸的是,当时我还不知道它是否会成为多点触控,所以我不能使用它。
onTouchStart
onTouchMove
onTouchEnd
event.preventDefault()
event.stopPropagation()
第二条本办法中设置touch-action: none的document.body。这适用于Chrome Android,但如果我对所有元素(组件除外)都进行了设置,则只能使其与Firefox Android一起使用。因此,尽管这是可行的,但似乎可能会带来不良的副作用和性能问题。 编辑: 进一步的测试表明,只有在触摸开始之前设置CSS的情况下,此功能才适用于Chrome。换句话说,如果我在检测到两根手指时注入CSS样式,则将touch-action被忽略。因此,这在Chrome上没有用。
touch-action: none
document.body
touch-action
我也尝试在组件安装上添加新的事件侦听器:
document.body.addEventListener("touchmove", ev => { ev.preventDefault(); ev.stopImmediatePropagation(); }, true);
(与相同touchstart)。这样做在Firefox Android中有效,但在Chrome Android中不起作用。
touchstart
我的想法不多了。是否有可靠的跨浏览器方法来实现Google显然所做的工作,还是他们在每个浏览器上使用了多种黑客工具和大量测试来使其正常运行?如果有人指出我的方法有误或提出新的方法,我将不胜感激。
TL; DR:{ passive: false }注册事件处理程序时我不见了。
{ passive: false }
我在使用preventDefault()Chrome时遇到的问题是由于其滚动“干预”(阅读:破坏了WebIE风格)。简而言之,由于preventDefault()可以更快地处理不调用的处理程序,因此在addEventListenernamed中添加了一个新选项passive。如果设置为,true则事件处理程序承诺不会调用preventDefault(如果调用,则将忽略该调用)。但是,Chrome决定更进一步,并{passive:true}设置默认设置(自版本56开始)。
preventDefault()
addEventListener
passive
true
preventDefault
{passive:true}
解决方案是将事件侦听器passive显式设置为false:
false
window.addEventListener('touchmove', ev => { if (weShouldStopDefaultScrollAndZoom) { ev.preventDefault(); ev.stopImmediatePropagation(); }; }, { passive: false });
请注意,这会对性能产生负面影响。
附带说明一下,似乎我误解了touch- actionCSS,但是我仍然不能使用它,因为需要在触摸顺序开始之前设置它。但是,如果不是这种情况,则可能是性能更高,并且似乎在所有适用的平台上都受支持(Mac上的Safari不支持,但iOS上则支持)。这篇文章说得最好:
touch- action
对于您的情况,您可能想要标记文本区域(或其他内容)“ touch-action:none”以禁用滚动/缩放,而不禁用所有其他行为。
CSS属性应该在组件上设置,而不是document像我那样设置:
document
<div style="touch-action: none;"> ... my component ... </div>
就我而言,我仍然需要使用passive事件处理程序,但是很高兴知道这些选项……希望它能对某人有所帮助。