【问题标题】:How to stop double-touching in iOS from scaling the entire page如何在iOS中停止双击缩放整个页面
【发布时间】:2021-02-07 23:38:21
【问题描述】:

我有一个 web 应用程序,其内部窗格位于外部窗口中。
用户可以进行各种触摸操作,例如通过两指捏合放大内窗格,不放大外窗,触摸移动以平移内窗等。
在 Android 版 Chrome 上,该应用按预期运行。
但是在 iOS 设备 (iPad) 上的 Safari,当快速双击内窗口的边界线时,整个窗口有时会缩放。

我发现可以通过在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();
};

但我仍然可以通过快速双击内部窗口的边框线来重新调整整个窗口。

iOS 中如何防止整个窗口在双击时缩放?


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

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

谢谢

【问题讨论】:

    标签: javascript ios touch-event


    【解决方案1】:

    我找到了一些 hacky 解决方案。

    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。

    【讨论】:

      【解决方案2】:

      我找到了解决方案。
      我有以下 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())。

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

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

      • 当触摸画布元素(div3 是最近的带有事件监听器的上游元素)时,会应用常规行为。

      • 当触摸边框元素 (div2) 时,event.preventDefault() 被应用于事件监听器,并阻止调整整个窗口大小的默认行为(我想禁用它)。

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

      【讨论】:

        猜你喜欢
        • 2013-03-26
        • 2012-02-19
        • 2013-11-08
        • 2012-05-29
        • 2018-02-20
        • 2014-05-31
        • 2017-09-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多