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

IT技术 javascript iphone ipad orientation
2021-02-10 22:50:40

当我以纵向模式启动我的应用程序时,它工作正常。然后我旋转到横向并按比例放大。为了让它在横向模式下正确缩放,我必须双击某些东西,首先放大(正常的双击行为)然后再一次放大(再次,正常的双击行为) . 当它缩小时,它会缩小到横向模式的正确新比例。

切换回纵向似乎更一致;也就是说,它处理缩放,以便当方向变回纵向时比例是正确的。

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

对于视口元内容,我将初始比例设置为 1.0,并且我没有设置最小或最大比例(我也不想)。我将宽度设置为设备宽度。

有任何想法吗?我知道很多人会很高兴有一个解决方案,因为它似乎是一个长期存在的问题。

6个回答

Jeremy Keith ( @adactio ) 在他的博客Orientation and scale上有一个很好的解决方案

通过不在标记中设置最大比例来保持标记的可扩展性。

<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() { /* */ });
有用。但是,我注意到用户必须捏开两次才能进行缩放。我猜这是因为maximum-scale=1.0手势开始后仍然有效。有没有什么办法解决这一问题?
2021-03-18 22:50:40
这不起作用有两个原因:1) 它禁用了 1 号手势开始,导致用户需要两次手势。2)它在用户将第一个手势加倍后中断,所以它只有在用户根本不做手势时才有效。- 每个人都应该看看下面的 Andrew Ashbacher 的解决方案。真的行。
2021-03-23 22:50:40
这肯定比禁用缩放更好吗?!我找到的最好的解决方法:)
2021-03-31 22:50:40
它有效,但是我观察到如果我使用捏缩放手势然后旋转屏幕,问题会再次出现。不知道如何修复它。
2021-03-31 22:50:40
嗯,这仍然禁用缩放功能。有没有人有一个不这样做的简单解决方案?
2021-04-12 22:50:40

Scott Jehl提出了一个奇妙的解决方案,它使用加速度计来预测方向变化。此解决方案响应迅速且不会干扰缩放手势。

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

工作原理:此修复程序通过侦听设备的加速度计来预测即将发生方向变化的时间。当它认为即将发生方向更改时,脚本禁用用户缩放,允许正确发生方向更改,同时禁用缩放。一旦设备的方向接近直立,或者在其方向发生变化后,脚本将再次恢复缩放。这样,当页面正在使用时,用户缩放永远不会被禁用。

缩小的来源:

/*! 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(c.x);i=Math.abs(c.y);h=Math.abs(c.z);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);
好的!看起来像一个优雅的解决方案。
2021-03-16 22:50:40
经过进一步测试,这是一种不可靠的解决方案:( 这是不一致的,在查看代码后,我明白了为什么......定义的运动“阈值”并不总是达到,尤其是当你拿着 ipad 时旋转时的角度
2021-03-16 22:50:40
对于使用旋转锁定的任何人来说都可能会产生令人讨厌的后果......他们可能会以某个角度握住手机并失去缩放能力 - 用户不知道为什么
2021-03-21 22:50:40
这应该是公认的答案!!!!我希望在浪费一个小时在上面的解决方案上之前先看到这个:)
2021-04-06 22:50:40

我遇到了同样的问题,设置maximum-scale=1.0 对我有用。

编辑:如评论中所述,这会禁用用户缩放,除非内容超过宽度分辨率。如前所述,这可能不明智。在某些情况下也可能需要它。

视口代码:

    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0;">
我注意到所有这些方法似乎都阻止了基于媒体查询的 CSS 正确注册新设备宽度(例如:@media all 和 (max-width: 479px)
2021-03-18 22:50:40
缺点是残疾用户无法放大您的网站!
2021-03-29 22:50:40
杀死用户缩放是一个非常糟糕的主意。请参阅下面的 Andrew Ashbacher 的解决方案
2021-03-29 22:50:40
不错的解决方案。通过方向更改将页面保持在恒定缩放级别(相对于设备的宽度)做得很好。感谢分享!
2021-03-30 22:50:40
不确定 iPhone,但在 iPad 上这并不能解决问题,它只是阻止用户在浏览器放大方向更改时手动缩小。
2021-04-05 22:50:40

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

<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 事件,或者如果您希望它与平台无关(便于测试)window.innerWidth方法。

这是否也会阻止用户手动放大和缩小?
2021-03-24 22:50:40

MobileSafari 支持对象orientationchange上的事件window不幸的是,似乎没有一种方法可以通过 JavaScript 直接控制缩放。也许您可以动态编写/更改meta控制视口标签——但我怀疑这是否可行,它只会影响页面的初始状态。也许您可以使用此事件使用 CSS 实际调​​整内容的大小。祝你好运!

谢谢!是的,我尝试动态更改元标记视口值,但什么也没做。在我看来,如果您旋转到横向,您希望它正确缩放以保持比例,以便页面适合 Safari 窗口。这不是默认行为对我来说似乎很奇怪!
2021-04-11 22:50:40