禁用视口缩放iOS 10+ safari?

Sam*_* Su 149 mobile-safari viewport ios10 ios11 ios12

我已经更新我的iPhone 6加至10的iOS beta版本,只是发现,在移动Safari浏览器,您可以通过双击放大任何网页或捏忽略user-scalable=no在meta标签代码.我不知道这是一个错误或功能.如果它被视为一项功能,我们如何禁用视口缩放iOS 10 Safari?


在iOS 11/12发布,iOS 11和iOS 12 safari上更新仍然尊重user-scalable=no元标记.

Safari上的移动github网站

Jos*_*eph 90

在iOS 10上可以防止在Safari中进行网页扩展,但这将涉及到您的更多工作.我猜这个论点是,一定程度的困难应该阻止货币狂热的开发者将"用户可扩展=否"放入每个视口标签中,并使视力受损的用户感到不必要的困难.

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

你可以用这样的东西停止捏缩放:

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

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

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

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

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

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

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

  • 哇,这部分(我会在这里粘贴)对我来说非常有帮助.互联网上任何人都没有看到过这个问题.我花了几个小时来解决这个问题.我真的很失望Apple的UX设计选择,其中表单自动放大,但不要缩小.`如果你没有正确设置表单元素,专注于输入将自动缩放,并且由于你大部分都禁用了手动缩放,现在几乎不可能取消缩放.确保输入字体大小> = 16px (10认同)
  • 例如.全屏映射应用程序,在地图应用程序(Google Maps JS,Leaflet等)中有一个硬编码的缩放功能.谷歌建议添加一个元标记`<meta name ="viewport"content ="initial-scale = 1.0,user-scalable = no"/>`如果浏览器不尊重元标记,那么浏览器设计是非常糟糕的.另一个非常糟糕的设计是滑动后退/前进动作,这在iOS 9/10中无法阻止.它严重破坏了Web应用程序中的拖动操作. (5认同)
  • 似乎这不再适用于iOS 12.知道如何让这个适用于iOS 12吗? (5认同)
  • 如果用户用一根手指开始拖动,那么将第二根手指放在屏幕上就可以进行双指缩放.您可以在`touchmove`上使用`preventDefault`禁用缩放和滚动.您无法(完全)禁用缩放而不禁用滚动. (4认同)
  • 请注意,touchstart hack是不一致的......如果你设法回避它,你会陷入非常不舒服的状态 (3认同)
  • @Stewart是的,它是特定于iOS的.但这个问题也是如此. (2认同)
  • 我敢肯定,只要在safari或可访问性设置中添加一个覆盖用户可缩放元标记的开关,苹果的代码就会少很多,这将真正改善可访问性。他们还应该有一个开关,以关闭变焦,并双击以适应有帕金森症的人。我们所有人都应该羞辱使用可访问性的苹果,因为这是将更多人推向其网络商店中仅“可访问”的应用的原因。除了获利之外,他们什么都没有给老鼠@sss。 (2认同)
  • iOS 13 将 false 更改为 {passive: false} (2认同)

Pau*_*rts 77

这是iOS 10中的新功能.

从iOS 10 beta 1发行说明:

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

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

  • "唯一可接受的用户案例是一个真实的网络应用程序,外观和感觉就像一个应用程序." - 就像你说的那样,这是一个真实的,可接受的用例,它不是那种罕见的...... (47认同)
  • 我有IOS 10.0.2,用户可扩展=否在我们的网站上不再禁用缩放...我们的主要问题是缩放是我们的固定侧面菜单..它只是打破布局..任何想法或解决方案吗?我知道缩放对于可访问性是有利的,我们使用js事件(锤子)和css在我们网站的特定部分进行缩放.我不明白为什么必须对每个人施加规则,似乎PC警察正在开始接管我们的开发世界?! (14认同)
  • @Karlth对于游戏开发者来说非常适合 (8认同)
  • 坏..我改变视口使用js并阻止缩放只有当网站上选择了一些元素时,现在由于这个"决定"而被打破.如果有人决定阻止它 - 有一个原因. (5认同)
  • @Onza:我不认为这很糟糕.我觉得这很好.禁用捏合/缩放(默认用户行为)被认为是错误的,很多移动网站都会这样做.唯一可接受的用户案例是一个真实的网络应用程序,外观和感觉就像一个应用程序. (4认同)
  • 这很糟糕......我们怎样才能让他们改变主意?...当你的webapp因为这个而中断时,你为什么会得到UI设计师呢? (3认同)
  • 我有一个网络应用程序,我想看起来和感觉像一个"真正的应用程序" - 而这种Safari忽略(双关语)完全混淆了用户体验.Safari的一个愚蠢的举动. (3认同)

Ped*_*dro 23

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

body {
  touch-action: pan-x pan-y;
}
Run Code Online (Sandbox Code Playgroud)

  • 当今最佳答案。它工作完美。 (2认同)
  • 在 iOS 15 上完美无缺 (2认同)

Cel*_*ane 14

看来这种行为在最新的beta中有所改变,在撰写本文时它是beta 6.

从iOS 10 Beta 6的发行说明中:

WKWebView现在默认尊重user-scalable=no视口.的客户WKWebView可以提高可访问性,并允许用户通过设置捏到变焦的所有页面WKWebViewConfiguration 属性ignoresViewportScaleLimitsYES.

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

编辑:已验证,iOS 10 Beta 6 user-scalable=no默认为我尊重.

  • 10.0.1这里.不尊重它.什么是苹果摆脱每个人都需要的功能.. (11认同)

iai*_*ton 14

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

  • @GuySopher iOS *不*仅提供`touch-action:none'仅`manipulatoin`,这留有捏缩放问题。 (5认同)
  • 这很棒 - 禁用双击变焦,同时留下捏缩放,这应该被认为是一个手势 - 双击不应该.1条狗是狗.1只狗+ 1只狗不是航天飞机制造的.它制造了2只狗,它们可以做你期望2只狗做的事情.我从没想过会有2只狗成为航天飞机.决不. (3认同)
  • 使用触摸动作:pan-x pan-y,修复它。 (3认同)
  • 这应该是公认的答案。您可以使用“触摸动作:无”来自己控制所有手势。 (2认同)

Cas*_*ius 9

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

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

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

  • 有人在iOS 12上尝试过吗?我添加了上面的代码,但对我的webapp却无济于事。仍然可以放大这个愚蠢的Safari。我的元视口标签如下所示:&lt;meta name =“ viewport” content =“ width = device-width,initial-scale = 1,maximum-scale = 1,user-scalable = no”&gt;`。 (3认同)
  • 这个适用于 iOS 13。我的 &lt;meta&gt; 标签包括:```&lt;meta name="viewport" content="width=device-width、initial-scale=1、maximum-scale=1、viewport-fit=cover 、 user-scalable=no、shrink-to-fit=no" /&gt;``` 和 ```&lt;meta name="HandheldFriendly" content="true"&gt;``` (3认同)
  • @PatrickDaVader 是的,找不到适用于 iOS 12 Safari 的任何可行解决方案。从所有不断的变焦中晕船。 (2认同)
  • @SterlingBourne 的回复对我有用!谢谢。他应该将其作为答案而不是评论发布,以便可以对其进行投票 &lt;meta name="viewport" content="width=device-width, initial-scale=1, Maximum-scale=1, viewport-fit=cover, user-scalable=no、shrink-to-fit=no" /&gt; 和 &lt;meta name="HandheldFriendly" content="true"&gt; (2认同)

spo*_*ker 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>
Run Code Online (Sandbox Code Playgroud)


Ham*_*med 7

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

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


小智 6

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

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

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

document.documentElement.addEventListener('touchmove', function (event) {
    event.preventDefault();      
}, false);
Run Code Online (Sandbox Code Playgroud)

希望它会有所帮助.

  • 这只适用于你的应用程序是完美的...如果你有可滚动的内容它不起作用...仍然很好的黑客在某些情况下. (7认同)
  • 这甚至禁用网站上的滚动..坏 (6认同)

Par*_*mod 6

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

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

  • iOS 13 将 false 更改为 {passive: false} (3认同)

jef*_*han 6

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

$(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)'
    }
  })
})
Run Code Online (Sandbox Code Playgroud)

?禁用捏缩放。

?禁用双击缩放。

?滚动不受影响。

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

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


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


Ale*_*aev 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();
  }
});
Run Code Online (Sandbox Code Playgroud)

受到互不寒冬要旨约瑟夫的回答的启发。


Ste*_*rne 5

根据要求,我已将我的评论转移到一个答案中,以便人们可以对其进行投票:

这在 90% 的时间适用于 iOS 13:

<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">

  • 为什么这个方法在 90% 的情况下都有效?我在我身上试过了,没用:( (4认同)