如何防止触摸事件的默认处理?

10 浏览
0 Comments

如何防止触摸事件的默认处理?

我正在尝试做类似于嵌入式谷歌地图的事情。我的组件应该忽略单触摸(允许用户滚动页面)和在组件之外的双指操作(允许用户缩放页面),但应该对双触摸做出反应(允许用户在组件内导航)并在这种情况下禁止任何默认操作。

我如何阻止触摸事件的默认处理,但只在用户用两根手指与我的组件交互时才这样做?

我尝试过:

  1. 我尝试捕获onTouchStartonTouchMoveonTouchEnd。结果发现,在FF Android上,在组件上进行缩放操作时,首先触发的事件是带有单触摸的onTouchStart,然后是带有两个触摸的onTouchStart,然后是onTouchMove。但在onTouchMove处理程序中调用event.preventDefault()event.stopPropagation()并不能(总是)阻止页面缩放/滚动。在第一次调用onTouchStart时阻止事件升级确实有帮助,但不幸的是,此时我还不知道是否会是多点触摸,所以我不能使用这种方法。
  2. 第二种方法是在document.body上设置touch-action: none。这在Chrome Android上可以工作,但是我只能在Firefox Android上使其工作,如果我将其设置在所有元素上(除了我的组件)。所以虽然这是可行的,但似乎可能会产生意想不到的副作用和性能问题。编辑:进一步测试发现,只有在触摸开始之前设置CSS样式,这种方法才适用于Chrome。换句话说,如果我在检测到2个手指时注入CSS样式,那么touch-action将被忽略。所以这在Chrome上没有用。
  3. 我还尝试在组件挂载时添加一个新的事件监听器:

    document.body.addEventListener("touchmove", ev => {
      ev.preventDefault();
      ev.stopImmediatePropagation();
    }, true);
    

    (对于touchstart也是一样)。这样做在Firefox Android上可以工作,但在Chrome Android上无效。

我已经没有更多的想法了。有没有一种可靠的跨浏览器方法来实现谷歌显然做到的,或者他们使用了多个hack并在每个浏览器上进行了大量测试才使其工作?如果有人指出我方法中的错误或提出一种新方法,我将不胜感激。

0