在触摸设备上禁用浏览器的双击“缩放”选项

179
我希望可以在浏览器上(在触摸设备上)禁用指定元素的双击缩放功能,而不影响所有缩放功能。例如:一个元素需要多次点击才能发生某些事情,在桌面浏览器上正常工作(如预期),但是在触摸设备浏览器上会发生缩放。

1
虽然不是用于缩放,但这里有一些其他必要的内容 - `-webkit-touch-callout: none;
-webkit-text-size-adjust: none; -webkit-user-select: none;
- Udayraj Deshmukh
1
它可能有所帮助(在我的情况下确实如此):但我注意到双击问题仅存在于div上,而不是canvas上。 - Matthieu Charbonnier
18个回答

191

仅使用CSS的解决方案

touch-action: manipulation添加到您想要禁用双击缩放的任何元素上,例如使用以下disable-dbl-tap-zoom类:

.disable-dbl-tap-zoom {
  touch-action: manipulation;
}
<button>plain button</button>

<button class="disable-dbl-tap-zoom">button with disabled double-tap zoom</button>

<p>A <b>plain</b> paragraph. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.</p>

<p class="disable-dbl-tap-zoom">A paragraph <b>with disabled double-tap zoom</b>. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.</p>

touch-action文档中(重点是我的):
引用: 操作 启用平移和捏放缩手势,但禁用其他非标准手势,例如双击缩放。
此值适用于Android和iOS。

1
@SergoPasoevi,你能创建一个不起作用的示例吗?我正在使用这个解决方案来支持iOS 12,而且对我很有效。 - Ross Allen
4
全身包裹touch-action: manipulation有哪些缺点? - oygen
3
双击图像时在最新的iOS上无法工作。 - Adam
1
它可能有所帮助(在我的情况下确实如此):但是双击问题仅存在于div上,而不是canvas上。 - Matthieu Charbonnier
3
应用以下代码input[type="button"]{ touch-action: manipulation; }后,在iOS 14.6上(使用Safari,手机而非平板电脑)运行良好。当我在页面其他地方双击时,它会放大或有时选择内容,但当我点击按钮或者仅靠近按钮时,它总是会触发按钮而不会做其他任何事情。对于以后的读者,也许你可以更新顶部的编辑内容以表明它适用于按钮,但对于其他元素,可能(因为Adam Silver称它不适用于图像)不起作用。 - Luc
显示剩余6条评论

76
<head>
<title>Site</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> 
etc...
</head>

我最近使用过它,在iPad上运行良好。 我没有在Android或其他设备上进行测试(因为该网站仅在iPad上显示)。


26
很遗憾,那将禁用所有缩放功能,但这并不是我的问题。我只想禁用特定的元素。 - Wouter Konecny
6
这个解决方案怎么样?它只适用于iOS,但或许可以进行调整?:https://gist.github.com/2047491 - Kablam
3
@WouterKonecny 如果您删除用户代理检查,它应该可以在支持touchstart事件的任何设备上运行。要检测这些设备,您可以使用类似isEventSupported的东西。 - nxt
10
苹果现在正式忽视这个问题。 https://github.com/w3c/html/issues/602 - catamphetamine
某些元素在14.3和15.0中无法正常工作。https://jsbin.com/sizavudima/edit?html,output - David Vielhuber
显示剩余3条评论

47

禁用双击缩放的CSS全局样式(适用于任何元素):

  * {
      touch-action: manipulation;
  }

操作

启用平移和捏合缩放手势,但禁用其他非标准手势,如双击缩放。

谢谢Ross,我的答案是他的延伸:https://dev59.com/eWkv5IYBdhLWcg3waAJT#53236027


1
这应该被标记为答案。我尝试将其仅放在html和body上,但在iOS 13.2中无效。这个有效。 - R OMS
这个代码本身在iOS 13上不起作用,但与这段代码结合使用可以完全阻止React应用的双击缩放功能。 document.getElementById('root').addEventListener('click', () => {}) - Sergei
苹果在iOS13上禁用了“双击缩放”功能,你怎么能说它在iOS13上不起作用呢? - oygen
1
@michaelmcgurk,这个对你有用吗?我在iOS 14上无法让它工作。双击任何元素(如div /标题)仍会导致双击缩放。 - Jonathan002
截至2021年,它似乎在iOS Safari上无法正常工作。 - Chewie The Chorkie
显示剩余2条评论

39

我知道这可能有点老了,但我找到了一个完美解决我的问题的方法。无需疯狂的元标签和停止内容缩放。

我不确定它在跨设备上是否有效,但它完全按照我想要的方式工作。

$('.no-zoom').bind('touchend', function(e) {
  e.preventDefault();
  // Add your code here. 
  $(this).click();
  // This line still calls the standard click event, in case the user needs to interact with the element that is being clicked on, but still avoids zooming in cases of double clicking.
})

这将简单地禁用普通的触摸功能,然后再次调用标准的点击事件。这可以防止移动设备缩放,但其他方面功能正常。

编辑:现在已经经过时间测试,并在几个实时应用程序中运行。看起来它可以在各种浏览器和平台上100%运行。上述代码应该可以作为大多数情况下的复制粘贴解决方案,除非您想在点击事件之前自定义行为。


2
这会禁用点击,我认为这不是一个好的解决方案,抱歉。 - Pixelomo
7
你不需要JS来完成这个操作,你只需要设置CSS属性pointer-events: none即可。 - Pixelomo
2
谢谢,这个方法完美地解决了处理增量/减量按钮时不会禁用整个页面缩放的问题。 - Ramón
2
这个解决方案的问题在于,如果您滚动页面时手指碰巧放在按钮上,它会认为您点击了它。 - Curtis
1
如果我理解正确的话,在某些需要可信事件的情况下,这可能会失败(例如点击触发全屏或其他实验时,需要可信事件,这意味着由用户/操作系统触发)。 - Manuel Graf
显示剩余4条评论

31

我只是想正确回答我的问题,因为有些人不会阅读回答下面的评论。所以这里是:

(function($) {
  $.fn.nodoubletapzoom = function() {
      $(this).bind('touchstart', function preventZoom(e) {
        var t2 = e.timeStamp
          , t1 = $(this).data('lastTouch') || t2
          , dt = t2 - t1
          , fingers = e.originalEvent.touches.length;
        $(this).data('lastTouch', t2);
        if (!dt || dt > 500 || fingers > 1) return; // not double-tap

        e.preventDefault(); // double tap - prevent the zoom
        // also synthesize click events we just swallowed up
        $(this).trigger('click').trigger('click');
      });
  };
})(jQuery);

这不是我写的,我只做了一些修改。我在这里找到了仅适用于iOS版本: https://gist.github.com/2047491 (感谢Kablam)


1
这似乎不起作用,至少在SIII(带有Android 4.0.4)上不起作用。我尝试绑定到document、body、window、*,但都不行。 - Max
我也试过了,在Safari/iPad、Android Chrome上可以运行,但在Android默认浏览器上无法运行。 - Strae
5
jQuery不是JavaScript,希望能有一个不使用库的示例来说明如何实现这一点。 - Martijn Scheffer
再次强调,jQuery不是JavaScript,也不应该被鼓励使用,因为它与基于更现代思想的网站(如Angular)不兼容。请仔细阅读问题。 - Martijn Scheffer
问题没有提到jQuery,jQuery不是标准,已经完全过时了,而且鼓励编写难以阅读的代码。你真的想继续这个争论吗?我有点累了。 - Martijn Scheffer
显示剩余3条评论

17

如果你需要一份不需要jQuery的版本,我修改了Wouter Konecny的答案(该答案也是通过修改Johan Sundström这个代码片段而创建的),使其使用原生JavaScript。

function preventZoom(e) {
  var t2 = e.timeStamp;
  var t1 = e.currentTarget.dataset.lastTouch || t2;
  var dt = t2 - t1;
  var fingers = e.touches.length;
  e.currentTarget.dataset.lastTouch = t2;

  if (!dt || dt > 500 || fingers > 1) return; // not double-tap

  e.preventDefault();
  e.target.click();
}

然后在touchstart上添加事件处理程序,调用此函数:

myButton.addEventListener('touchstart', preventZoom); 

3
很棒。只是想提一下,为了调用这个功能需要添加一个addEventListener。myButton.addEventListener('touchstart', preventZoom); - martin jakubik

12

1
这个可以用...但是如果我想要禁用缩放,但保留其它的触摸事件呢?我有一个很大的表格,使用这个方法同时也会禁用滚动。 - FrenkyB
2
如果您只想摆脱双击缩放,您应该将值设置为“touch-action: manipulate;”这仍然允许平移和捏合缩放。重要提示:这也有助于消除浏览器引入的单击延迟,以实现双击缩放。请参见https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action。 - cschuff
这个类应该添加在哪个HTML标签上? - Razvan Zamfir
我认为您可以将其添加到任何不希望用户缩放的元素中。例如,在我的情况下,我不希望用户缩放页面的任何部分,因此我将其添加到了body标签中。 - Jonathan Morales Vélez

10
* {
    -ms-touch-action: manipulation;
    touch-action: manipulation;
}

禁用触摸屏幕上的双击缩放功能,包括Internet Explorer浏览器。

7

禁用移动设备上的双击缩放 (2023年IOS Safari解决方案):

我发现对于移动Safari浏览器,使用meta标签方法并不是可行的解决方案。以下是适用于我的解决方案。

有效的解决方案:

.selector {
   touch-action: manipulation;
}

通过简单地添加一个 manipulation 触摸动作,所有应用以下规则的按钮将不会在连续点击按钮时缩放。

示例网站:计算器应用


1
非常棒的计算器应用和你在Github个人介绍页面非常赞! - Ronen Rabinovici

4

很不幸,大部分以上的代码都无法正常工作

这几行简单的代码就可以解决问题

document.addEventListener('dblclick', function(event) {
    event.preventDefault();
}, { passive: false });

我可以确认这是在我的情况下唯一有效的解决方案。 - Lars Rönnbäck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接