如何阻止 iOS 中的双击缩放整个页面

How to stop double-touching in iOS from scaling the entire page

我有一个 web 应用程序,在外部 window 内有一个内部窗格。
用户可以进行各种触摸操作,例如通过双指捏合放大内部窗格,不放大外部-window,触摸移动以平移内部 window 等..
在 Android 上的 Chrome 上,该应用按预期运行。
但是 iOS 设备 (iPad) 上的 Safari,当快速双击内部 window.

的边界线时,整个 window 有时会缩放

我发现我可以通过在 touchend 事件上添加一个事件侦听器来防止这种副作用。

window.addEventListener('touchend', onTouchEnd5, {capture: false, passive: false});

并在绑定函数中调用 event.preventDefault()

async function onTouchEnd5( event ) {
    console.log('BEG onTouchEnd5');
    event.preventDefault();
};

但这会导致另一个副作用,即触摸点击按钮不会被拦截。

我尝试在其他可能由默认行为触发的事件上添加事件监听器,例如click, dblclick, touchcancel, fullscreenchange, fullscreenerror, resize, onscroll
想法是尝试阻止这些事件的默认行为,以防在那里引起副作用。 (合理的是iphone/ipad can trigger unexpected events)。
从上面列出的事件中,事件 onscroll 被触发。 在此事件的绑定函数中,我添加了 preventDefault():

function onScroll5( event ) {
    console.log('BEG onScroll5');
    event.preventDefault();
};

但是我仍然可以通过快速双击内部 window 的边界线来重新缩放整个 window。

如何在双击时防止整个 window 缩放 iOS?


注:
整个window的缩放是最新观察到的。
在此之前,我发现整个 window 在例如在 window.
的另一部分做双指捏 在这种情况下,解决方案是在另一个事件侦听器绑定函数上添加 preventDefault。

鉴于应用中有多个事件,一个更普遍的问题是:
有没有办法防止整个 window 在任何情况下一起缩放?

谢谢

我找到了一个有点老套的解决方案。

  1. 制作一个名为 /mobile 的页面,或使用 / 并将所有内容放在名为 /maincontent 的页面上,然后在下一步中使用 URL。
  2. 在该页面中,添加一个 iframe,如下所示:
<iframe src='/ (or "maincontent")' style='width:100vw;height:100vh;top:0;left:0;position:fixed;border:none;' frameborder='0'></iframe>

我知道这有点老套,但它适用于 iOS 14.

我找到了解决方案。
我有以下 DOM 结构:

<body>
    <div id="div1">
        <div id="div2">
            <div id="div3">
                <canvas>...</canvas>
            </div>
        </div>
        <div id="div4">
            <div id="div5"><button></div>
        </div>
    </div>
</body>

我最初尝试在 onTouchStartDiv3() 中添加 event.preventDefault(),它监听 canvas 元素中的事件(具有事件监听器的最近的上游元素是 div3)。
这解决了边框双击的问题,但又引起了另一个问题:
onTouchMoveDiv3() 被立即调用(甚至没有移动手指),这导致了其他副作用。 (我在关卡中有一些状态机,这取决于 onTouchStartDiv3(), onTouchMoveDiv3(), onTouchEndDiv3())。

然后我尝试在 window/document 级别 (onTouchStartWindow(), onTouchStartDocument()) 添加事件侦听器并在其中调用 event.preventDefault()
这再次解决了边框双击的问题,但又引起了另一个问题:
按钮 (div5) 停止响应触摸事件。
原因是,因为按钮上没有特定的事件侦听器,事件被更高层拦截,并应用默认行为。
因为 window/document 事件侦听器调用了 event.preventDefault(),所以阻止了此行为(这阻止了按钮响应触摸事件)。

最后,我在触摸边框级别添加了事件监听器(div2)。
在 onTouchStartDiv2() 内部,我将 event.currentTarget (div2) 与事件起源的 event.target 进行比较。
如果 event.target 是 div2,则事件源自单击边框,因此我应用 event.preventDefault() 以防止在 iOS 上调整整个图像的副作用。
如果 event.target 是 而不是 div2 那么事件源自点击,例如在 canvas 中,所以我 应用 event.preventDefault() 来维护状态机。
按照这个逻辑,我解决了这个问题:

  • 当触摸 canvas 元素时(div3 是最近的具有事件侦听器的上游元素),应用了常规行为。

  • 触摸边框元素 (div2) 时,event.preventDefault() 应用于事件侦听器,并防止调整整个 window (我想禁用它)。

  • 触摸按钮元素 (div5) 时,将应用常规行为,因此按钮会响应触摸事件。