如何重置iPhone上的方向更改的Web应用程序的缩放/缩放?

当我以纵向模式启动我的应用程序时,它工作正常。 然后,我旋转到景观,并扩大规模。 为了使它在横向模式下正确缩放,我必须双击两次,第一次放大(正常的双击行为),再次放大(再次,正常的双击行为) 。 当缩小时,缩小到横向模式的正确的新比例。

切换回肖像似乎更一致地工作; 也就是说,它处理缩放,以便在方向变回肖像时缩放比例是正确的。

我想弄清楚这是否是一个错误? 或者如果这是可以用JavaScript修复的东西?

使用视口元内容,我将初始缩放设置为1.0,而不是设置最小或最大缩放比例(我也不想)。 我将宽度设置为设备宽度。

有任何想法吗? 我知道很多人会感激有一个解决scheme,因为它似乎是一个持续的问题。

Jeremy Keith( @adactio )在他的博客定位和规模上有很好的解决scheme

通过不在标记中设置最大比例来保持标记可伸缩。

<meta name="viewport" content="width=device-width, initial-scale=1"> 

然后禁用JavaScript上的可扩展性,直到使用此脚本再次允许可伸缩性时为止:

 if (navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i)) { var viewportmeta = document.querySelector('meta[name="viewport"]'); if (viewportmeta) { viewportmeta.content = 'width=device-width, minimum-scale=1.0, maximum-scale=1.0, initial-scale=1.0'; document.body.addEventListener('gesturestart', function () { viewportmeta.content = 'width=device-width, minimum-scale=0.25, maximum-scale=1.6'; }, false); } } 

2014年12月22日更新:
在iPad 1上这不起作用,它在事件监听器上失败。 我发现删除.body修复:

 document.addEventListener('gesturestart', function() { /* */ }); 

斯科特Jehl提出了一个奇妙的解决scheme,使用加速度计来预测方向的变化。 该解决scheme非常灵敏,不会干扰缩放手势。

https://github.com/scottjehl/iOS-Orientationchange-Fix

工作原理:这个解决scheme通过收听设备的加速度计来预测方位变化即将发生的时间。 当它认为即将进行的方向改变时,脚本禁用用户缩放,允许方向改变正确发生,禁用缩放。 一旦设备的方向接近直立,或者方向改变后,脚本就会恢复缩放。 这样,用户缩放从不被禁用,而页面正在使用。

精简来源:

 /*! A fix for the iOS orientationchange zoom bug. Script by @scottjehl, rebound by @wilto.MIT License.*/(function(m){if(!(/iPhone|iPad|iPod/.test(navigator.platform)&&navigator.userAgent.indexOf("AppleWebKit")>-1)){return}var l=m.document;if(!l.querySelector){return}var n=l.querySelector("meta[name=viewport]"),a=n&&n.getAttribute("content"),k=a+",maximum-scale=1",d=a+",maximum-scale=10",g=true,j,i,h,c;if(!n){return}function f(){n.setAttribute("content",d);g=true}function b(){n.setAttribute("content",k);g=false}function e(o){c=o.accelerationIncludingGravity;j=Math.abs(cx);i=Math.abs(cy);h=Math.abs(cz);if(!m.orientation&&(j>7||((h>6&&i<8||h<8&&i>6)&&j>5))){if(g){b()}}else{if(!g){f()}}}m.addEventListener("orientationchange",f,false);m.addEventListener("devicemotion",e,false)})(this); 

我有同样的问题,并设置最大规模= 1.0为我工作。

编辑:正如在评论中提到的,除了当内容超出宽度分辨率时,这将禁止用户缩放。 如上所述,这可能不是明智的。 在某些情况下也可能需要。

视口代码:

  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0;"> 

如果您在视口中设置了宽度:

 <meta name = "viewport" content = "width=device-width; initial-scale=1.0; maximum-scale=1.0;" /> 

然后改变方向它会随机放大有时(特别是如果你在屏幕上拖动)来解决这个不要在这里设置宽度我使用:

 <meta id="viewport" name="viewport" content="initial-scale=1.0; user-scalable=0; minimum-scale=1.0; maximum-scale=1.0" /> 

这将修复缩放无论发生什么,然后你可以使用window.onorientationchange事件或者如果你想它是平台独立(方便testing)的window.innerWidth方法。

MobileSafari支持window对象上的orientationchange事件。 不幸的是,似乎没有办法通过JavaScript直接控制缩放。 也许你可以dynamic地编写/更改控制视口的meta标记 – 但是我怀疑这会起作用,它只影响页面的初始状态。 也许你可以使用这个事件来实际调整你的内容使用CSS。 祝你好运!

我创build了一个横向/纵向布局的工作演示,但是必须禁用缩放才能在没有JavaScript的情况下工作:

http://matthewjamestaylor.com/blog/ipad-layout-with-landscape-portrait-modes

我一直在我的项目中使用这个function。

 function changeViewPort(key, val) { var reg = new RegExp(key, "i"), oldval = document.querySelector('meta[name="viewport"]').content; var newval = reg.test(oldval) ? oldval.split(/,\s*/).map(function(v){ return reg.test(v) ? key+"="+val : v; }).join(", ") : oldval+= ", "+key+"="+val ; document.querySelector('meta[name="viewport"]').content = newval; } 

所以只需addEventListener:

 if( /iPad|iPhone|iPod|Android/i.test(navigator.userAgent) ){ window.addEventListener("orientationchange", function() { changeViewPort("maximum-scale", 1); changeViewPort("maximum-scale", 10); } } 

我发现了一个新的解决方法,与我见过的其他方法不同,禁用本地iOS缩放,而是在JavaScript中实现缩放function。

SérgioLopes提供了各种其他缩放/方向问题解决scheme的优秀背景: 修复了着名的iOS变焦问题,改变了朝向 。

 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" id="viewport" content="user-scalable=no,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0" /> <title>Robocat mobile Safari zoom fix</title> <style> body { padding: 0; margin: 0; } #container { -webkit-transform-origin: 0px 0px; -webkit-transform: scale3d(1,1,1); /* shrink-to-fit needed so can measure width of container http://stackoverflow.com/questions/450903/make-css-div-width-equal-to-contents */ display: inline-block; *display: inline; *zoom: 1; } #zoomfix { opacity: 0; position: absolute; z-index: -1; top: 0; left: 0; } </style> </head> <body> <input id="zoomfix" disabled="1" tabIndex="-1"> <div id="container"> <style> table { counter-reset: row cell; background-image: url(http://upload.wikimedia.org/wikipedia/commons/3/38/JPEG_example_JPG_RIP_010.jpg); } tr { counter-increment: row; } td:before { counter-increment: cell; color: white; font-weight: bold; content: "row" counter(row) ".cell" counter(cell); } </style> <table cellspacing="10"> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> <tr><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td><td> </table> </div> <script> (function() { var viewportScale = 1; var container = document.getElementById('container'); var scale, originX, originY, relativeOriginX, relativeOriginY, windowW, windowH, containerW, containerH, resizeTimer, activeElement; document.addEventListener('gesturestart', function(event) { scale = null; originX = event.pageX; originY = event.pageY; relativeOriginX = (originX - window.pageXOffset) / window.innerWidth; relativeOriginY = (originY - window.pageYOffset) / window.innerHeight; windowW = window.innerWidth; windowH = window.innerHeight; containerW = container.offsetWidth; containerH = container.offsetHeight; }); document.addEventListener('gesturechange', function(event) { event.preventDefault(); if (originX && originY && event.scale && event.pageX && event.pageY) { scale = event.scale; var newWindowW = windowW / scale; if (newWindowW > containerW) { scale = windowW / containerW; } var newWindowH = windowH / scale; if (newWindowH > containerH) { scale = windowH / containerH; } if (viewportScale * scale < 0.1) { scale = 0.1/viewportScale; } if (viewportScale * scale > 10) { scale = 10/viewportScale; } container.style.WebkitTransformOrigin = originX + 'px ' + originY + 'px'; container.style.WebkitTransform = 'scale3d(' + scale + ',' + scale + ',1)'; } }); document.addEventListener('gestureend', function() { if (scale && (scale < 0.95 || scale > 1.05)) { viewportScale *= scale; scale = null; container.style.WebkitTransform = ''; container.style.WebkitTransformOrigin = ''; document.getElementById('viewport').setAttribute('content', 'user-scalable=no,initial-scale=' + viewportScale + ',minimum-scale=' + viewportScale + ',maximum-scale=' + viewportScale); document.body.style.WebkitTransform = 'scale3d(1,1,1)'; // Without zoomfix focus, after changing orientation and zoom a few times, the iOS viewport scale functionality sometimes locks up (and completely stops working). // The reason I thought this hack would work is because showing the keyboard is the only way to affect the viewport sizing, which forces the viewport to resize (even though the keyboard doesn't actually get time to open!). // Also discovered another amazing side effect: if you have no meta viewport element, and focus()/blur() in gestureend, zoom is disabled!! Wow! var zoomfix = document.getElementById('zoomfix'); zoomfix.disabled = false; zoomfix.focus(); zoomfix.blur(); setTimeout(function() { zoomfix.disabled = true; window.scrollTo(originX - relativeOriginX * window.innerWidth, originY - relativeOriginY * window.innerHeight); // This forces a repaint. repaint *intermittently* fails to redraw correctly, and this fixes the problem. document.body.style.WebkitTransform = ''; }, 0); } }); })(); </script> </body> </html> 

这可以改善,但为了我的需要,它避免了我见过的所有其他解决scheme中出现的主要缺陷。 到目前为止,我只在iOS4的iPad 2上使用移动Safari进行了testing。

focus()/ blur()是一种解决方法,可以防止在改变方向和缩放几次之后偶尔出现的缩放function的locking。

设置document.body.style将强制进行全屏重绘,这样可以避免在缩放后重绘失败时偶尔出现间歇性问题。

Elisabeth可以通过将“id”属性添加到元标签来dynamic更改视口内容:

 <meta name="viewport" id="view" content="user-scalable=yes, width=device-width minimum-scale=1, maximum-scale=1" /> 

那么你可以通过javascript调用:

 document.getElementById("view").setAttribute('content','user-scalable=yes, width=device-width, minimum-scale=1, maximum-scale=10'); 

这是另一种方法,这似乎运作良好。

  1. 将元标记设置为将视口限制为scale = 1,这将防止缩放:

    <meta name =“viewport”content =“width = device-width,initial-scale = 1,minimum-scale = 1,maximum-scale = 1”>

  2. 使用JavaScript,稍后更改元标记以允许缩放:

    setTimeout(function(){document.querySelector(“meta [name = viewport]”)。setAttribute('content','width = device-width,initial-scale = 1');},500);

  3. 再次与JavaScript,在方向更改,重新加载页面:

    window.onorientationchange = function(){window.location.reload();};

每次重新调整设备时,页面都会重新加载,最初不会缩放。 但1/2秒后,缩放能力恢复。

发现一个非常容易实施的修复。 在窗体完成时将焦点设置为字体大小为50px的文本元素。 如果文本元素被隐藏,但是隐藏这个元素似乎并不起作用,可以通过将元素的颜色属性设置为不透明来轻松完成。