disable viewport zooming iOS 10+ safari?

2019-01-02 17:19发布

I've update my iPhone 6 plus to iOS 10 beta version and just found that in mobile safari, you can zoom any webpages by double tapping or pinching IGNORE the user-scalable=no code in the meta tag. I don't know whether it's a bug or feature. If it's considered as a feature, how do we disable viewport zooming iOS 10 safari ?


updated on iOS 11/12 release, iOS 11 and iOS 12 safari still DO NOT respect the user-scalable=no meta tag.

mobile github site on Safari

15条回答
谁念西风独自凉
2楼-- · 2019-01-02 17:39

I tried the previous answer about pinch-to-zoom

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

however sometime the screen still zoom when the event.touches.length > 1 I found out the best way is using touchmove event, to avoid any finger moving on the screen. The code will be something like this:

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

Hope it will help.

查看更多
ら面具成の殇う
3楼-- · 2019-01-02 17:41

The workaround that works in Mobile Safari at this time of writing, is to have the the third argument in affffdEventListener be { passive: false }, so the full workaround looks like this:

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

You may want to check if options are supported to remain backwards compatible.

查看更多
若你有天会懂
4楼-- · 2019-01-02 17:42

It appears that this behavior is supposedly changed in the latest beta, which at the time of writing is beta 6.

From the release notes for iOS 10 Beta 6:

WKWebView now defaults to respecting user-scalable=no from a viewport. Clients of WKWebView can improve accessibility and allow users to pinch-to-zoom on all pages by setting the WKWebViewConfiguration property ignoresViewportScaleLimits to YES.

However, in my (very limited) testing, I can't yet confirm this to be the case.

Edit: verified, iOS 10 Beta 6 respects user-scalable=no by default for me.

查看更多
萌妹纸的霸气范
5楼-- · 2019-01-02 17:43

I came up with a pretty naive solution, but it seems to work. My goal was to prevent accidental double-taps to be interpreted as zoom in, while keeping pinch to zoom working for accessibility.

The idea is in measuring time between the first touchstart and second touchend in a double tap and then interpreting the last touchend as click if the delay is too small. While preventing accidental zooming, this method seems to keep list scrolling unaffected, which is nice. Not sure if I haven't missed anything though.

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

Inspired by a gist from mutewinter and Joseph's answer.

查看更多
宁负流年不负卿
6楼-- · 2019-01-02 17:43

As odd as it sounds, at least for Safari in iOS 10.2, double tap to zoom is magically disabled if your element or any of its ancestors have one of the following:

  1. An onClick listener - it can be a simple noop.
  2. A cursor: pointer set in CSS
查看更多
君临天下
7楼-- · 2019-01-02 17:44

It's possible to prevent webpage scaling in safari on iOS 10, but it's going to involve more work on your part. I guess the argument is that a degree of difficulty should stop cargo-cult devs from dropping "user-scalable=no" into every viewport tag and making things needlessly difficult for vision-impaired users.

Still, I would like to see Apple change their implementation so that there is a simple (meta-tag) way to disable double-tap-to-zoom. Most of the difficulties relate to that interaction.

You can stop pinch-to-zoom with something like this:

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

Note that if any deeper targets call stopPropagation on the event, the event will not reach the document and the scaling behavior will not be prevented by this listener.

Disabling double-tap-to-zoom is similar. You disable any tap on the document occurring within 300 milliseconds of the prior tap:

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

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.

If you're trying to solve this in a WKWebView in a native app, the solution given above is viable, but this is a better solution: https://stackoverflow.com/a/31943976/661418. And as mentioned in other answers, in iOS 10 beta 6, Apple has now provided a flag to honor the meta tag.

Update May 2017: I replaced the old 'check touches length on touchstart' method of disabling pinch-zoom with a simpler 'check event.scale on touchmove' approach. Should be more reliable for everyone.

查看更多
登录 后发表回答