禁用视口缩放iOS 10+野生动物园?


164

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


在iOS 11/12发行版上进行了更新,iOS 11和iOS 12野生动物园仍然遵守user-scalable=nometa标签。

Safari上的移动github网站


2
辅助功能:在iOS 10上的Safari中值得注意的是twitter.com/thomasfuchs/status/742531231007559680/photo/1
ErikE

87
不,不是。对于正常的Web内容,这是不好的做法。对于Web应用程序,默认的缩放行为会完全破坏可用性。例如,没人想放大频道上的按钮,因为他们轻按了两次;也不想放大视频游戏的一部分,因为他们轻按了两次跳转按钮。首先添加此功能是有原因的,仅仅因为一些“网页设计师”不知道他们在做什么,就破坏了每个人的可用性是没有意义的。对网站设计者大喊大叫,然后退出浏览器。
dgatwood '17

36
说这是“不好的做法”是一种意见,并不能改变苹果坚持采用网络标准的事实,即社区花费数月/年/数十年的经验来跨平台实施并对其进行大量废c。苹果为什么要规定网页设计师不知道自己在做什么?可怕的争论。
samrap'2

2
就个人而言,我认为这源于在线样板代码,开发人员只是盲目地复制和粘贴代码,而不知道代码的目的是什么。
威廉·伊斯特

7
答案很简单,Apple:将禁用meta标签设为默认关闭可访问性设置。那些需要它的人将拥有它,而不会惩罚那些不需要它的人。
鲁宾·马丁内斯(Ruben Martinez)

Answers:


94

可以防止在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现在提供了标记来纪念meta标签。

2017年5月更新:我用一种更简单的'check event.scale on touchmove'方法代替了禁用pinz-zoom的旧的'touchstart上的check touches length'方法。应该对每个人都更可靠。


3
请注意,touchstart hack是不一致的...如果您回避它,则会陷入非常不舒服的状态
Sam Saffron

5
例如。全屏地图应用程序,则在地图应用程序中硬编码了缩放功能(Google Maps JS,Leaflet等)。Google建议添加一个元标记<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />,如果浏览器不遵守该元标记,那将是非常糟糕的浏览器设计。另一个类似非常糟糕的设计的问题是通过滑动来实现后退/前进动作,这在iOS 9/10中无法避免。它严重破坏了Web应用程序内部的拖动动作。
TimoKähkönen16年

4
如果用户开始用一根手指拖动,则将另一根手指放在屏幕上将能够进行捏缩放。您可以通过preventDefault启用禁用缩放和滚动touchmove。您不能(完全)禁用缩放而不禁用滚动。
Paolo

10
哇,这部分(我将在此处粘贴)对我有很大帮助。我还没有在网上看到任何其他人提到的这一点。解决这个问题花了我几个小时。我对Apple的UX设计选择感到非常失望,因为表单会自动放大,但随后又不会缩小。If you don't set up your form elements right, focusing on an input will auto-zoom, and since you have mostly disabled manual zoom, it will now be almost impossible to unzoom. Make sure the input font size is >= 16px.
Ryan

6
看来这不再适用于iOS 12。知道如何使此功能适用于iOS 12吗?
TJR

78

这是iOS 10中的新功能。

从iOS 10 beta 1发行说明:

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

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


4
@Onza:我不认为这很糟糕。我觉得很好 禁用捏缩/缩放(默认用户行为)被认为是不好的,许多移动网站都这样做。唯一可以接受的用例是外观和感觉像应用程序的真实Web应用程序。
wouterds

6
不好。我仅在网站上选择了某些元素后才使用js更改视口并阻止缩放,但由于这种“决定”,该视图已被破坏。如果有人决定阻止它-这是有原因的。
振亚

9
@Karlth对于游戏开发人员来说非常适合
Sandeep

14
我有IOS 10.0.2,user-scalable = no不会在我们的网站上不再禁用缩放功能。缩放功能的主要问题是固定侧面菜单。它只是破坏了布局。对此有任何想法或解决方案吗?我知道缩放对可访问性有益,我们使用js事件(锤子)和CSS在网站的特定部分提供了缩放功能。接管我们的开发世界?!
webkit

49
“唯一可以接受的用户案例是外观和感觉像应用程序的真实Web应用程序。” -这是,像你说的,真实的,可接受的使用情况下,是不是那个罕见的..
弗洛里

21

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


1
“操作”不会阻止捏缩放,只有两次轻按缩放。
Moos

4
这应该是公认的答案。您可以touch-action: none;自己控制所有手势。
Guy Sopher

3
这非常好-禁用两次缩放,同时保持捏缩缩放(应视为手势)-不应双击。1条狗是一条狗。1条狗+ 1条狗不是航天飞机制造的。它养了两只狗,它们做的事情是您期望两只狗做的。我从没想到有两只狗会成为航天飞机。决不。
拉里

5
@GuySopher的iOS并没有提供touch-action: none唯一的manipulatoin,这让夹变焦的问题,因为它是。
humanityANDpeace

14

看来此行为在最新的beta中有所更改,在撰写本文时为beta 6。

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

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

但是,在我的测试(非常有限)中,我还不能确定是否确实如此。

编辑:已验证,iOS 10 Beta 6 user-scalable=no默认情况下对我而言。


11
这里是10.0.1。不尊重它。什么是每个人都需要..苹果摆脱的特点
lifwanian

1
这指的WKWebView 不是 Safari。资料来源:我们的一个地图应用程序坏了,我们知道如何解决。
法比奥·波洛尼

啊哈!抱歉,我是在这里寻找相同错误/功能的解决方案时来到这里的,并且我WKWebView以为原始问题是WKWebView在编写答案时问到的。因此,我想在第一个Beta版本中,Apple更改了WKWebView移动Safari和移动Safari 的行为,然后在Beta 6中,他们恢复了行为,WKWebView但保留了移动Safari 的行为。
Cellane

1
10.0.2不尊重user-scalable=no。我不确定为什么他们会撤消此操作,只是将其恢复原状,然后再次将其删除。
艾丹·哈基米安

13

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

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

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


3
有人在iOS 12上尝试过吗?我添加了上面的代码,但对我的webapp却无济于事。仍然可以放大这个愚蠢的Safari。我的中继检视区标记看起来像这样BTW: <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
Patrick DaVader

1
@PatrickDaVader是的,找不到适用于iOS 12 Safari的任何有效解决方案。从不断的变焦中晕船。
杰米·伯奇

1
此版本可在iOS 13中使用。我的<meta>标签包括:<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">
Sterling Bourne,

1
@SterlingBourne复制了您的设置。确实有效,但仅在90%的时间中有效。不知道为什么不一直如此。
Hillcow

1
@SterlingBourne的回复对我有用!谢谢。他应该将其发布为答案而不是评论,以便可以对其进行投票<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“>
Gene Black

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>


在使用Hammer.js时,我也一直在尝试解决此问题,并且可以确认是否可以通过向.preventDefault所有锤子手势处理程序添加A 来防止视口缩放。我一起使用滑动/捏/平移/敲击,将其添加到所有处理程序中,我不知道是否有特定的功能正在执行。
科南

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

希望会有所帮助。


7
仅当您的应用非常合适时,此方法才有效。如果您确实具有可滚动的内容,则它不起作用。
eljamz

8
这甚至禁用了网站上的滚动。.BAD
堵住嘴

@eljamz感谢您告诉我,是的..我的应用非常适合在屏幕上显示。
Chihying Wu

@Gags我尚未测试滚动功能,谢谢您告诉我。
Chihying Wu

6

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

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

2
iOS 13将false更改为{passive:false}
wayofthefuture

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)'
    }
  })
})

✔禁用捏变焦。

✔禁用双击缩放。

✔滚动不受影响。

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

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


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


这适用于运行iOS 11.2的iPad模拟器。在运行iOS 11.3的真实iPad上,它不起作用。我添加了console.log以确保触发了事件,并使其出现在控制台中。这与iOS 11.3有关吗?还是带有真实设备?
Mathieu R.

1
@MathieuR。这是一个iOS 11.3问题。可以通过使用addEventListener基于答案之一并将其{ passive: false }作为options参数而不是进行纠正false。但是,为了向后兼容,false除非passive支持选项字段,否则需要通过。见developer.mozilla.org/en-US/docs/Web/API/EventTarget/...
约什-加拉格尔

@JoshGallagher您能提供一个可行的例子吗?在iOS11上,没有答案对我有用。
米克

在“gesturestart” - >的preventDefault对我的作品在写作时在iOS 12,2
迈克尔·卡姆登

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

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


5

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

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

我的用例也是带有自定义缩放控件的整页3d场景。如果苹果没有一种解决方法明确地忽略了用户规模,那就太沉没了:没有元数据。
尼克·比利克

1

听起来很奇怪,至少对于iOS 10.2中的Safari而言,如果您的元素或其任何祖先具有以下任一状态,则无法进行双击缩放:

  1. 一个onClick侦听器-它可以是一个简单的Noop。
  2. 一个cursor: pointer在CSS集

怎么捏?
Sam Su

不幸的是,这种解决方案不包括捏缩放。为此,我们使用了以下提议的解决方案:stackoverflow.com/a/39594334/374196
mariomc

对我不起作用。我正在使用此测试页在iPod Touch上使用10.2.1 Beta 4,然后双击任何灰色方块缩放:jsbin.com/kamuta/quiet
robocat

1
我在react应用程序中有一个跨度,它不起作用。
FMD

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在内的所有界面都应该“缩小” -可以在某些地方使用。我还是设计,避免用户这样做是为了让你的用户界面访问他们,不惜一切代价。


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

1

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

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


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

不幸的是,这仅在您的页面非常合适时才有效,而在您具有可滚动内容时则无效
Shoe

嗯 以我的经验(iOS 10.3),此功能可滚动显示的内容很好。
jeff_mcmahan

0

这为我工作:

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

我尝试过此操作,它确实防止了捏缩缩放,但是它禁用了视口的触摸滚动,因此您无法再上下滚动页面。
TGR
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.