Safari iPhone - How to detect zoom level and offse

2019-01-21 17:49发布

问题:

I looking for options on how to track user zooming and panning on a page when viewed in Safari on an iPhone. Safari exposes move and gesture events, so theoretically I can keep a running tally of pan and zoom operations, but that seems like overkill since the browser must track that internally.

Is this information exposed through the Document Object Model?

回答1:

When you zoom in, window.innerWidth is adjusted, but document.documentElement.clientWidth is not, therefore:

var zoom = document.documentElement.clientWidth / window.innerWidth;

(I've tested iOS4, without viewport <meta>).

However, I wouldn't rely on it for anything important. DOM viewport sizes/pixel sizes in mobile browsers are a complete mess.



回答2:

According to the Safari Web Content Guide, zoom events (double tap) are not exposed, so I'm not sure how you can track this.

I do not believe this information is exposed through the DOM.



回答3:

On Mobile Safari and Android, here is an accurate way to measure how much the page has been zoomed.

Try it here: http://jsbin.com/cobucu/3 - change zoom then click measure.

Technique is to add a top level div:

<body>
<div id=measurer style="position:absolute;width:100%"></div>

and use the calculation:

function getZoom(){
    return document.getElementById('measurer').offsetWidth / window.innerWidth;
}

The only problem is finding a tidy way to detect that the user has changed zoom (pinch, double tap, etc). Options:

  • webkitRequestAnimationFrame: very reliable, but likely to cause jankiness if using animations (due to performance hit)
  • setInterval: reliable but very ugly
  • touch events: look for two fingers or double tap: ugly and maybe difficult to make 100% reliable
  • window.onresize + window.onorientationchange + window.onscroll: simple but totally unreliable (Edit: and onscroll can cause performance problems in WKWebView or Mobile Safari 8 or greater).

PS: Windows Phone needs a different solution (pinch-zoom doesn't change the viewport - pinch-zoom on Windows has its own separate viewport that is not visible to javascript).



回答4:

I actually think things might have moved on a little since Steve's answer, as having a look at the content guide link he provided I can see a section on Handling Multi-Touch Events and also Handling Gesture Events.

Haven't tried them yet but they look pretty promising. I'll provide an update once I've checked them out and have a demo link available...



回答5:

I measure zoom this way (works on iOS only):

screenOrientedWidth = screen.width;
if (window.orientation == 90) {
    screenOrientedWidth = screen.height;
}
return screenOrientedWidth / window.innerWidth;

It doesn't depend of how wide content is.

However, in iOS Safari window.innerWidth isn't correct inside a gestureend handler. You should defer such calculation for later execution. In GWT, I use scheduleDeferred, but I can't say how to implement this in pure JavaScript.



回答6:

If you are using any elements with location:fixed this can get complicated, as the location:fixed coordinates are relative to the unzoomed window, where window coordinates are relative to the zoomed viewport. More info: How to position a fixed-location element on IOS browser when zoomed?



标签: iphone safari