182

我已经将我的 iPhone 6 plus 更新到 iOS 10 beta 版本,并且刚刚发现在移动 safari 中,您可以通过双击或捏住忽略元标记中的代码来缩放任何网页user-scalable=no。不知道是bug还是功能。如果它被视为一项功能,我们如何禁用视口缩放 iOS 10 safari ?


在 iOS 11/12 版本上更新,iOS 11 和 iOS 12 safari 仍然尊重user-scalable=no元标记。

Safari 上的移动 github 站点

4

19 回答 19

101

在 iOS 10 上的 safari 中可以防止网页缩放,但这需要您做更多的工作。我猜这个论点是一定程度的困难应该阻止货物狂热的开发人员将“user-scalable=no”放到每个视口标签中,并使视力受损的用户不必要地困难。

尽管如此,我还是希望看到 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);

如果您没有正确设置表单元素,则专注于输入将自动缩放,并且由于您基本上禁用了手动缩放,因此现在几乎不可能取消缩放。确保输入字体大小 >= 16px。

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

2017 年 5 月更新:我用更简单的“在 touchmove 上检查 event.scale”方法替换了旧的“在 touchstart 上检查触摸长度”禁用捏合缩放的方法。应该对每个人都更可靠。

于 2016-07-25T16:37:38.477 回答
80

这是 iOS 10 中的一项新功能。

来自 iOS 10 beta 1 发行说明:

  • 为了提高 Safari 中网站的可访问性,即使网站设置user-scalable=no在视口中,用户现在也可以捏合缩放。

我希望我们很快就会看到一个 JS 插件以某种方式禁用它。

于 2016-06-16T12:24:54.777 回答
25

我已经能够使用touch-action单个元素的 css 属性来解决这个问题。尝试设置touch-action: manipulation;经常被点击的元素,如链接或按钮。

于 2017-01-18T14:40:25.547 回答
23

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

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

您可能需要检查是否支持选项以保持向后兼容。

于 2018-08-06T15:01:40.330 回答
15

似乎这种行为在最新的 beta 版中有所改变,在撰写本文时是 beta 6。

来自 iOS 10 Beta 6 的发行说明:

WKWebView现在默认user-scalable=no从视口尊重。的客户端可以通过将 属性设置为来WKWebView提高可访问性并允许用户在所有页面上进行捏拉缩放。WKWebViewConfigurationignoresViewportScaleLimitsYES

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

编辑:已验证,iOS 10 Beta 6user-scalable=no对我来说默认尊重。

于 2016-08-18T11:41:23.947 回答
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>

于 2016-10-06T07:19:42.690 回答
8

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

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

于 2021-07-06T23:12:34.303 回答
7

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

window.addEventListener(
    "touchmove",
    function(event) {
        if (event.scale !== 1) {
            event.preventDefault();
        }
    },
    { passive: false }
);
于 2018-06-12T18:11:55.240 回答
7

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

$(function () {
  if (!(/iPad|iPhone|iPod/.test(navigator.userAgent))) return
  $(document.head).append(
    '<style>*{cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0)}</style>'
  )
  $(window).on('gesturestart touchmove', function (evt) {
    if (evt.originalEvent.scale !== 1) {
      evt.originalEvent.preventDefault()
      document.body.style.transform = 'scale(1)'
    }
  })
})

✔ 禁用捏缩放。

✔ 禁用双击缩放。

✔ 滚动不受影响。

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

注意:根据您的喜好调整 iOS 检测。更多关于这里


lukejacksonPiotr Kowalski道歉,他们的答案以修改后的形式出现在上面的代码中。

于 2017-08-04T00:06:24.153 回答
6

我想出了一个非常幼稚的解决方案,但它似乎有效。我的目标是防止意外的双击被解释为放大,同时保持捏缩放工作以实现可访问性。

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

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();
  }
});

灵感来自 mutewinterJoseph 的回答

于 2017-10-07T19:00:39.590 回答
6

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

document.addEventListener('touchmove', function(event) {
    event = event.originalEvent || event;
    if(event.scale > 1) {
        event.preventDefault();
    }
}, false);
于 2017-01-11T10:04:12.333 回答
6

我尝试了上一个关于捏到缩放的答案

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

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

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

希望它会有所帮助。

于 2016-09-20T12:38:00.167 回答
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">

于 2020-02-28T19:48:56.127 回答
1

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

  1. 一个 onClick 监听器 - 它可以是一个简单的 noop。
  2. cursor: pointerCSS中的一组
于 2017-01-12T18:57:28.623 回答
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);
于 2017-10-03T07:33:45.423 回答
1

在以下情况下往往会发生无意缩放:

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

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

<button onclick='event.preventDefault()'>Prevent Default</button>
<button style='touch-action: manipulation'>Touch Action Manipulation</button>

这两者都阻止 Safari (iOS 10.3.2)放大按钮。如您所见,一种仅是 JavaScript,另一种仅是 CSS。适当使用。

这是一个演示:https ://codepen.io/lukejacksonn/pen/QMELXQ

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

于 2017-08-01T16:03:40.450 回答
1

在当前版本的 Safari 中,这不再起作用。您必须通过传递 {passiv:false} 将第二个参数定义为非被动

 document.addEventListener('touchmove', function(e) {
 e.preventDefault();
}, { passive: false });
于 2020-09-03T14:07:25.607 回答
0

这对我有用:

document.documentElement.addEventListener('touchmove', function (event) {
    event.preventDefault();
}, false);
于 2019-01-03T19:43:15.950 回答
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)'
    }
});
于 2017-07-27T13:40:30.640 回答