禁用视口缩放iOS 10+ safari?

时间:2016-06-14 09:32:49

标签: mobile-safari ios10 ios11 viewport ios12

我已将iPhone 6 plus更新为iOS 10测试版,并且发现在移动版Safari中,您可以通过双击或捏住 IGNORE user-scalable=no来缩放任何网页元标记中的代码。我不知道它是否是一个错误或功能。如果它被视为一项功能,我们如何禁用视口缩放iOS 10 Safari?

在iOS 11/12版本,iOS 11和iOS 12 Safari上更新

仍然尊重user-scalable=no元标记。

mobile github site on Safari

20 个答案:

答案 0 :(得分:82)

在iOS 10上可以防止Safari浏览器中的网页扩展,但这将涉及到您的更多工作。我猜这个论点是,一定程度的困难应该阻止货币崇拜开发者将“用户可扩展=否”放入每个视口标签中,并为视力受损的用户带来不必要的困难。

尽管如此,我还是希望Apple改变他们的实现,以便有一种简单的(元标记)方式来禁用双击缩放。大多数困难与这种互动有关。

您可以使用以下内容停止捏合缩放:

document.addEventListener('touchmove', function (event) {
  if (event.scale !== 1) { event.preventDefault(); }
}, false);

请注意,如果任何更深层的目标在事件上调用stopPropagation,则事件将无法到达文档,并且此侦听器将不会阻止缩放行为。

禁用双击缩放类似。您可以在之前的点按300毫秒内禁用对文档的任何点击:

var lastTouchEnd = 0;
document.addEventListener('touchend', function (event) {
  var now = (new Date()).getTime();
  if (now - lastTouchEnd <= 300) {
    event.preventDefault();
  }
  lastTouchEnd = now;
}, false);

如果您没有正确设置表单元素,关注输入将自动缩放,并且由于您大部分已禁用手动缩放,现在几乎不可能取消缩放。确保输入字体大小为&gt; = 16px。

如果您尝试在本机应用中的WKWebView中解决此问题,上面给出的解决方案是可行的,但这是一个更好的解决方案:https://stackoverflow.com/a/31943976/661418。正如其他答案中所提到的,在iOS 10 beta 6中,Apple现在提供了一个标志来表示元标记。

2017年5月更新:我用更简单的'touch event.scale on touchmove'方法取代了旧的'touch touch on touchstart'方法,禁用了双指缩放功能。应该对每个人都更可靠。

答案 1 :(得分:76)

这是iOS 10中的新功能。

来自iOS 10 beta 1发行说明:

  
      
  • 为了改善Safari网站的可访问性,即使网站在视口中设置<form action="addnew.php" method="post" enctype="multipart/form-data"> <input type="text" name="title" placeholder="Title"> <input type="text" name="location" placeholder="location"> <input type="file" name="file"> <input type="submit" value="add"> </form> ,用户现在也可以进行缩放。
  •   

我希望我们很快会看到一个JS加载项以某种方式禁用它。

答案 2 :(得分:14)

看来这种行为在最新的测试版中有所改变,在撰写本文时是测试版。

从iOS 10 Beta 6的发行说明:

  

WKWebView现在默认尊重视口中的user-scalable=no。   WKWebView的客户端可以改善可访问性并允许用户访问   通过设置WKWebViewConfiguration来缩放所有页面   财产ignoresViewportScaleLimitsYES

然而,在我的(非常有限的)测试中,我还不能确认是这种情况。

编辑:经过验证,默认情况下iOS 10 Beta 6尊重user-scalable=no

答案 3 :(得分:14)

我已经能够使用单个元素上的touch-action css属性来修复此问题。尝试在常用的元素上设置touch-action: manipulation;,例如链接或按钮。

答案 4 :(得分:8)

我花了大约一个小时寻找更强大的javascript选项,但没有找到。碰巧的是,在过去的几天里,我一直在摆弄hammer.js(Hammer.js是一个可以让你轻松操纵各种触摸事件的图书馆),而且大多数都是在我试图做的事情上失败了。

有了这个警告,并且理解我绝不是一个javascript专家,这是我想出的一个解决方案,它基本上利用hammer.js捕获捏缩放和双击事件,然后记录并丢弃它们。

确保在页面中包含hammer.js,然后尝试将此javascript保留在某个位置:

< script type = "text/javascript" src="http://hammerjs.github.io/dist/hammer.min.js"> < /script >
< script type = "text/javascript" >

  // SPORK - block pinch-zoom to force use of tooltip zoom
  $(document).ready(function() {

    // the element you want to attach to, probably a wrapper for the page
    var myElement = document.getElementById('yourwrapperelement');
    // create a new hammer object, setting "touchAction" ensures the user can still scroll/pan
    var hammertime = new Hammer(myElement, {
      prevent_default: false,
      touchAction: "pan"
    });

    // pinch is not enabled by default in hammer
    hammertime.get('pinch').set({
      enable: true
    });

    // name the events you want to capture, then call some function if you want and most importantly, add the preventDefault to block the normal pinch action
    hammertime.on('pinch pinchend pinchstart doubletap', function(e) {
      console.log('captured event:', e.type);
      e.preventDefault();
    })
  });
</script>

答案 5 :(得分:6)

检查touchove事件中的比例因子,然后阻止触摸事件。

document.addEventListener('touchmove', function(event) {
    event = event.originalEvent || event;
    if(event.scale > 1) {
        event.preventDefault();
    }
}, false);

答案 6 :(得分:5)

我尝试了之前关于捏合缩放的答案

document.documentElement.addEventListener('touchstart', function (event) {
    if (event.touches.length > 1) {
        event.preventDefault();
    }
}, false);

然而有时当 event.touches.length&gt;屏幕仍然缩放时1 我发现最好的方法是使用touchmove事件,以避免任何手指在屏幕上移动。代码将是这样的:

document.documentElement.addEventListener('touchmove', function (event) {
    event.preventDefault();      
}, false);

希望它会有所帮助。

答案 7 :(得分:5)

根据要求,我已将我的评论转移到答案,以便人们可以投票:

在iOS 13上90%的时间有效:

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover, user-scalable=no, shrink-to-fit=no" />

<meta name="HandheldFriendly" content="true">

答案 8 :(得分:5)

我提出了一个非常天真的解决方案,但似乎有效。 我的目标是防止意外双击被解释为放大,同时保持捏缩放工作以便于访问。

我们的想法是在双击中测量第一个touchstart和第二个touchend之间的时间,然后如果延迟太小则将最后touchend解释为点击。虽然防止意外缩放,这种方法似乎保持列表滚动不受影响,这很好。不知道我有没有错过任何东西。

let preLastTouchStartAt = 0;
let lastTouchStartAt = 0;
const delay = 500;

document.addEventListener('touchstart', () => {
  preLastTouchStartAt = lastTouchStartAt;
  lastTouchStartAt = +new Date();
});
document.addEventListener('touchend', (event) => {
  const touchEndAt = +new Date();
  if (touchEndAt - preLastTouchStartAt < delay) {
    event.preventDefault();
    event.target.click();
  }
});

受到gist from mutewinterJoseph's answer的启发。

答案 9 :(得分:4)

我们可以通过注入一个样式规则和拦截缩放事件来获得我们想要的一切:

{
    margin-left: auto;
}

✔禁用捏拉缩放。

✔禁用双击缩放。

✔滚动不受影响。

✔禁用点击突出显示(在iOS上按照样式规则触发)。

注意:根据自己的喜好调整iOS检测。更多关于here

lukejackson Piotr Kowalski 致歉,其答案在上面的代码中以修改后的形式出现。

答案 10 :(得分:3)

在撰写本文时,此方法在Mobile Safari中的解决方法是将addEventListener中的第三个参数设为{ passive: false },因此完整的解决方法如下所示:

document.addEventListener('touchmove', function (event) {
  if (event.scale !== 1) { event.preventDefault(); }
}, { passive: false });

您可能希望check if options are supported保持向后兼容。

答案 11 :(得分:2)

在我的特定情况下,我使用Babylon.js创建一个3D场景,我的整个页面由一个全屏画布组成。 3D引擎有自己的缩放功能,但在iOS上,缩放到缩放会干扰它。我更新了@Joseph的答案以克服我的问题。为了禁用它,我发现我需要将{passive:false}作为选项传递给事件监听器。以下代码适用于我:

window.addEventListener(
    "touchmove",
    function(event) {
        if (event.scale !== 1) {
            event.preventDefault();
        }
    },
    { passive: false }
);

答案 12 :(得分:1)

无意中缩放往往发生在:

  • 用户双击接口的组件
  • 用户使用两个或多个数字(捏合)
  • 与视口交互

为防止双击行为,我找到了两个非常简单的解决方法:

data

这两个都阻止按钮上的缩放中的Safari(iOS 10.3.2)。正如您所看到的,只有一个是JavaScript,另一个只是CSS。适当使用。

以下是演示:https://codepen.io/lukejacksonn/pen/QMELXQ

我还没有试图阻止捏合行为(主要是因为我倾向于不为网络创建多点触控界面,其次我已经认识到可能包括本机app UI在内的所有界面都应该“捏”缩放“ - 在某些地方。我仍然会设计避免用户这样做,以便不惜一切代价让他们可以访问您的UI。

答案 13 :(得分:1)

发现这个简单的工作似乎阻止了双击缩放:

    // Convert touchend events to click events to work around an IOS 10 feature which prevents
    // developers from using disabling double click touch zoom (which we don't want).
    document.addEventListener('touchend', function (event) {
        event.preventDefault();
        $(event.target).trigger('click');
    }, false);

答案 14 :(得分:1)

听起来很奇怪,至少对于iOS 10.2中的Safari,如果您的元素或其任何祖先具有以下之一,则双击缩放会被神奇地禁用:

  1. 一个onClick监听器 - 它可以是一个简单的noop。
  2. 在CSS
  3. 中设置cursor: pointer

答案 15 :(得分:1)

使用“touch-action: pan-x pan-y”禁用“双指缩放”和“双击缩放”。它适用于我测试过的所有触摸屏/手机,包括 iOS Safari 14.5.1。

body {
  touch-action: pan-x pan-y;
}

答案 16 :(得分:0)

我在iOS(iPhone 6,iOS 10.0.2)上使用我的页面检查了所有上述答案,但没有成功。这是我的工作解决方案:

$(window).bind('gesturestart touchmove', function(event) {
    event = event.originalEvent || event;
    if (event.scale !== 1) {
         event.preventDefault();
         document.body.style.transform = 'scale(1)'
    }
});

答案 17 :(得分:0)

这对我有用:

document.documentElement.addEventListener('touchmove', function (event) {
    event.preventDefault();
}, false);

答案 18 :(得分:0)

如果上述方法都不适合您,只需将框中的字体大小设置为16px即可解决问题。

答案 19 :(得分:0)

在当前版本的safari中,此功能不再起作用。您必须通过传递{passiv:false}

将第二个参数定义为非被动参数
 document.addEventListener('touchmove', function(e) {
 e.preventDefault();
}, { passive: false });