当前位置: 首页 > 面试题库 >

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

常嘉平
2023-03-14
问题内容

我正在尝试做类似于嵌入式Google地图的操作。我的组件应忽略单点触摸(允许用户滚动页面),并在其自身外部捏合(允许用户缩放页面),但应对双键触摸做出反应(允许用户在组件内部导航),并在这种情况下禁止任何默认操作。

如何防止触摸事件的默认处理,仅在用户用两只手指与我的组件进行交互的情况下?

我尝试过的

  1. 我尝试捕获onTouchStartonTouchMoveonTouchEnd。事实证明,在FF Android上,对部件进行捏合时触发的第一个事件是单击onTouchStart,然后触摸onTouchStart两次,然后是onTouchMove。但是,调用event.preventDefault()event.stopPropagation()in onTouchMove处理程序并不会(总是)停止页面缩放/滚动。防止在第一个呼叫中发生事件升级onTouchStart 确实有帮助 -不幸的是,当时我还不知道它是否会成为多点触控,所以我不能使用它。

  2. 第二条本办法中设置touch-action: nonedocument.body。这适用于Chrome Android,但如果我对所有元素(组件除外)都进行了设置,则只能使其与Firefox Android一起使用。因此,尽管这是可行的,但似乎可能会带来不良的副作用和性能问题。 编辑: 进一步的测试表明,只有在触摸开始之前设置CSS的情况下,此功能才适用于Chrome。换句话说,如果我在检测到两根手指时注入CSS样式,则将touch-action被忽略。因此,这在Chrome上没有用。

  3. 我也尝试在组件安装上添加新的事件侦听器:

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

(与相同touchstart)。这样做在Firefox Android中有效,但在Chrome Android中不起作用。

我的想法不多了。是否有可靠的跨浏览器方法来实现Google显然所做的工作,还是他们在每个浏览器上使用了多种黑客工具和大量测试来使其正常运行?如果有人指出我的方法有误或提出新的方法,我将不胜感激。


问题答案:

TL; DR:{ passive: false }注册事件处理程序时我不见了。

我在使用preventDefault()Chrome时遇到的问题是由于其滚动“干预”(阅读:破坏了WebIE风格)。简而言之,由于preventDefault()可以更快地处理不调用的处理程序,因此在addEventListenernamed中添加了一个新选项passive。如果设置为,true则事件处理程序承诺不会调用preventDefault(如果调用,则将忽略该调用)。但是,Chrome决定更进一步,并{passive:true}设置默认设置(自版本56开始)。

解决方案是将事件侦听器passive显式设置为false

window.addEventListener('touchmove', ev => {
  if (weShouldStopDefaultScrollAndZoom) {
    ev.preventDefault();
    ev.stopImmediatePropagation();
  };
}, { passive: false });

请注意,这会对性能产生负面影响。

附带说明一下,似乎我误解了touch- actionCSS,但是我仍然不能使用它,因为需要在触摸顺序开始之前设置它。但是,如果不是这种情况,则可能是性能更高,并且似乎在所有适用的平台上都受支持(Mac上的Safari不支持,但iOS上则支持)。这篇文章说得最好:

对于您的情况,您可能想要标记文本区域(或其他内容)“ touch-action:none”以禁用滚动/缩放,而不禁用所有其他行为。

CSS属性应该在组件上设置,而不是document像我那样设置:

<div style="touch-action: none;">
  ... my component ...
</div>

就我而言,我仍然需要使用passive事件处理程序,但是很高兴知道这些选项……希望它能对某人有所帮助。



 类似资料:
  • 问题内容: 如何防止onclick方法中的默认设置?我有一个传递自定义值的方法 问题答案: 让您的回调返回并将其传递给处理程序: 但是,要创建可 维护的 代码,您应该避免使用_“内联Javascript”_(即直接位于元素标签内的代码),并通过包含的Javascript源文件(称为unobtrusiveJavascript)修改元素的行为。 标记: 代码(单独的文件):

  • 问题内容: 好吧,所以我有4个图像视图。 当他们按下和向上时,我如何控制会发生什么 因此说: 其中一张图像被按下,textview变为1,但是当它们放开时,文本将变为0? 问题答案: 您需要使用OnTouchListener并让它在您的上监听。 例如: 这是一个看起来像的例子:

  • 问题内容: 该文档说明了这一点: 手势始于带有ACTION_DOWN的运动事件,该事件提供了下一个指针的位置。随着每个其他指针的下降或上升,框架将分别生成带有ACTION_POINTER_DOWN或ACTION_POINTER_UP的运动事件。 所以我在活动中完成了onTouchEvent函数的替代: 不幸的是,如果没有输入第二个。该活动包含2图2 OnTouchListener ,我知道 的on

  • 我有一个自定义模块,它使用Kentico API(DocumentHelper)更新文档的某些字段,然后发布,但我不希望它触发链接到文档页面类型的事件处理程序。我试着给它添加评论。Publish(“admin_edit”)希望我可以从WorkflowEventargs参数捕捉到它,但VersionComment属性总是返回null。肯蒂科有没有办法做到这一点? 更新字段: 事件处理程序:

  • 触摸操作概述 浏览器的触摸 API 由三个部分组成。 Touch:一个触摸点 TouchList:多个触摸点的集合 TouchEvent:触摸引发的事件实例 Touch接口的实例对象用来表示触摸点(一根手指或者一根触摸笔),包括位置、大小、形状、压力、目标元素等属性。有时,触摸动作由多个触摸点(多根手指)组成,多个触摸点的集合由TouchList接口的实例对象表示。TouchEvent接口的实例对

  • 我有一个父pom,它为我的其他组件提供所需的版本号变量 您必须使用分类器将补充工件附加到项目中,而不是替换它们 我发现这是因为jar打包固有的maven jar插件默认绑定,但我正在进行war打包,所以在war打包之后,默认jar执行开始并抛出上面的一个。任何停止违约的解决方案都将帮助我提前感谢。