gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 13:06:47 25 4
gpt4 key购买 nike

我正在尝试做类似 embedded Google maps 的事情做。我的组件应该忽略单点触摸(允许用户滚动页面)并在其外部捏合(允许用户缩放页面),但应该对双击使用react(允许用户在组件内部导航)并在这种情况下禁止任何默认操作。

如何防止触摸事件的默认处理,但仅限于用户用两根手指与我的组件交互的情况?

我尝试过的:

  1. 我 try catch 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 个手指时注入(inject) CSS 样式,那么 touch-action 将被忽略。所以这在 Chrome 上没有用。

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

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

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

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

最佳答案

TL;DR:注册事件处理程序时我缺少 { Passive: false }

我在 Chrome 中遇到的 preventDefault() 问题是由于它们的 scrolling "intervention" (阅读:打破网络 IE 风格)。简而言之,由于可以更快地处理不调用 preventDefault() 的处理程序,因此在 addEventListener 中添加了一个名为 passive 的新选项。如果设置为 true,则事件处理程序 promise 不会调用 preventDefault(如果调用,则该调用将被忽略)。然而,Chrome 决定更进一步,将 {passive: true} 设置为默认值(自版本 56 起)。

解决方案是调用事件监听器,并将 passive 显式设置为 false:

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

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

作为旁注,我似乎误解了 touch-action CSS,但是我仍然无法使用它,因为它需要在触摸序列开始之前设置。但如果情况并非如此,它可能性能更高,似乎是 supported on all applicable platforms (Mac 上的 Safari 不支持,但 iOS 上支持)。 This post说得最好:

For your case you probably want to mark your text area (or whatever) 'touch-action: none' to disable scrolling/zooming without disabling all the other behaviors.

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

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

就我而言,我仍然需要使用passive事件处理程序,但了解这些选项是件好事......希望它对某人有所帮助。

关于javascript - 如何防止触摸事件的默认处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49541173/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com