javascript - 方向更改Android和iOS后的最大视口高度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12643314/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
javascript max viewport height after orientation change Android & iOS
提问by Dan Kanze
The Goal:
目标:
To find the max viewport height of a device including the space of the address bar
so that we can dynamically resize the min-body and push our content up.
找到设备的最大视口高度,包括空间,address bar
以便我们可以动态调整最小主体的大小并将我们的内容向上推。
The Problem:
问题:
Mobile browsers handle orientation states differently and update DOM properties on orientation change differently.
移动浏览器以不同的方式处理方向状态,并在不同的方向改变时更新 DOM 属性。
Detect rotation of Android phone in the browser with JavaScript
使用 JavaScript 在浏览器中检测 Android 手机的旋转
With Android phones, screen.width
or screen.height
also updates as the device is rotated.
使用 Android 手机,screen.width
或screen.height
随着设备旋转而更新。
|==============================================================================|
| Device | Events Fired | orientation | innerWidth | screen.width |
|==============================================================================|
| iPad 2 | resize | 0 | 1024 | 768 |
| (to landscape) | orientationchange | 90 | 1024 | 768 |
|----------------+-------------------+-------------+------------+--------------|
| iPad 2 | resize | 90 | 768 | 768 |
| (to portrait) | orientationchange | 0 | 768 | 768 |
|----------------+-------------------+-------------+------------+--------------|
| iPhone 4 | resize | 0 | 480 | 320 |
| (to landscape) | orientationchange | 90 | 480 | 320 |
|----------------+-------------------+-------------+------------+--------------|
| iPhone 4 | resize | 90 | 320 | 320 |
| (to portrait) | orientationchange | 0 | 320 | 320 |
|----------------+-------------------+-------------+------------+--------------|
| Droid phone | orientationchange | 90 | 320 | 320 |
| (to landscape) | resize | 90 | 569 | 569 |
|----------------+-------------------+-------------+------------+--------------|
| Droid phone | orientationchange | 0 | 569 | 569 |
| (to portrait) | resize | 0 | 320 | 320 |
Because of this it is clear that to find the max viewport height no matter what orientation, using a single function to return the max height of a device will never be constant over a range of devices.
正因为如此,很明显,无论什么方向,要找到最大视口高度,使用单个函数返回设备的最大高度在一系列设备上永远不会恒定。
Other problems I have discovered that don't make these two play nice:
我发现的其他问题不会让这两个玩得很好:
- The
window.devicePixelRatio
property can return inconsistent heights when dividing bywindow.outerHeight
. - Delay
window.setTimeout(function() {}, time)
needs to be used to give DOM elements a chance to update after orientation change. window.outerHeight
is not updated on orientation changes for iOS devices. Usingscreen.availHeight
as a fallback includes the bottom nav bar as total height.- Using a
#header
,#content
,#footer
structure forces you to dynamically recalculate the#content{min-height}
to push the#footer
down when thebody
is dyamically updated.
window.devicePixelRatio
除以 时,该属性可能返回不一致的高度window.outerHeight
。window.setTimeout(function() {}, time)
需要使用延迟来让 DOM 元素在方向改变后有机会更新。window.outerHeight
未更新 iOS 设备的方向更改。使用screen.availHeight
作为后备包括底部导航栏为总高度。- 使用
#header
,#content
,#footer
结构会强制您在动态更新时动态重新计算#content{min-height}
以#footer
向下推body
。
A Solution:
一个解法:
First let's take a look at DIV structure:
首先我们来看看DIV结构:
<style>
#header,#content,#footer{width:100%;}
</style>
<body>
<div id="header"></div>
<div id="content"></div>
<div id="footer"></div>
</body>
We want to prevent devices from scaling on their own:
我们希望防止设备自行扩展:
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
We need help to have the ability to return a max viewport height and hide address bar for iOS:
我们需要帮助才能返回最大视口高度并隐藏 iOS 的地址栏:
<script src="iOS.js" type="text/javascript"></script>
Then detect if the device supports orientation change and use resize as a fallback:
然后检测设备是否支持方向更改并使用调整大小作为后备:
var iOS = (navigator.userAgent.match(/(iPad|iPhone|iPod)/i) ? true : false);
var android = (navigator.userAgent.match(/Android/i) ? true : false);
var supportsOrientationChange = "onorientationchange" in window;
var orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";
The belly of the beast:
兽腹:
function updateOrientation()
{
var orientation = (window.orientation);
if(android)
{
window.setTimeout(function() {
window.scrollTo(0,0);
var size = window.outerHeight/window.devicePixelRatio;
$('body').css('min-height', size + 'px');
var headerHeight = $('#header').height();
var footerHeight = $('#footer').height();
var contentHeight = size - (headerHeight+footerHeight);
$('#content').css('min-height', contentHeight + 'px');
window.scrollTo(0,1);
}, 200);
}
if(iOS)
{
window.setTimeout(function(){
window.scrollTo(0,0);
var size = iOS_getViewportSize();
var headerHeight = $('#header').height();
var footerHeight = $('#footer').height();
var contentHeight = size.height - (headerHeight+footerHeight);
$('#content').css('min-height', contentHeight + 'px');
window.scrollTo(0,1);
}, 0);
}
}
Add event listeners for page load and orientation event:
为页面加载和方向事件添加事件侦听器:
if(iOS)
{
iOS_addEventListener(window, "load", iOS_handleWindowLoad);
iOS_addEventListener(window, "orientationchange", iOS_handleOrientationChange);
iOS_addEventListener(window, "resize", iOS_handleReize);
}
addEventListener("load", function()
{
updateOrientation();
}, false);
addEventListener(orientationEvent, function() {
updateOrientation();
}, false);
Proof is in the pudding:
布丁中有证据:
iPhone 4 & 4s Portrait & Landscape
iPhone 4 和 4s 人像和风景
Android Portrait & Landscape
Android 人像和风景
The goal here is to minify this solution or make it better.
这里的目标是缩小此解决方案或使其更好。
回答by stubbsy
This is a simple solution that will append the browsers width and height to the document body on load and window resize.
这是一个简单的解决方案,它将在加载和窗口大小调整时将浏览器的宽度和高度附加到文档正文。
jQuery.event.add(window, "load", resize);
jQuery.event.add(window, "resize", resize);
function resize()
{
var h = jQuery(window).height();
var w = jQuery(window).width();
jQuery("body").css({"width": w, "height": h});
}
回答by frenchie
You could try a self-invoking closure that monitors the change in orientation by itself. Something like this:
您可以尝试使用自调用闭包来自行监控方向的变化。像这样的东西:
(function () {
var CurrentHeight;
(function CheckForOrientationChange() {
//var NewHeight = window.screen.availHeight / window.devicePixelRatio;
//var NewHeight = $(window).height();
var NewHeight = $('#WidthCheck').width();
if (CurrentHeight && CurrentHeight!== NewHeight ) {
alert(NewHeight); // change here
}
CurrentHeight = NewHeight;
setTimeout(CheckForOrientationChange, 1000);
})();
})();
Just drop this into the document ready function. For now it checks every second but you can shorten that interval. The jsfiddle is hereand you can test it by changing the size of the browser to simulate a mobile browser's change and then you can adapt the code to handle your action.
只需将其放入文档就绪功能中即可。现在它每秒检查一次,但您可以缩短该间隔。该的jsfiddle是在这里,你可以通过改变浏览器来模拟移动浏览器的变化的大小对其进行测试,然后你可以适应代码来处理你的动作。
回答by Dawson
Expected values returned in iOS simulator. I can't test for Android at the moment.
iOS 模拟器中返回的预期值。我目前无法测试 Android。
var supportsOrientationChange = "onorientationchange" in window;
var orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";
window.onload = updateOrientation();
window.addEventListener(orientationEvent, function() {
updateOrientation();
}, false);
function updateOrientation(){
switch(window.orientation){
case 0:
alert(window.outerHeight); // Returns '356' with browser chrome
break;
case -90:
alert('Landscape right');
break;
case 90:
alert(window.outerHeight); // Returns '208' w browser chrome
break;
case 180:
//alert('Portrait view - upside down');
break;
}
var orientation = (window.orientation);
}
(Note: This code will not test in a browser.)
(注意:此代码不会在浏览器中测试。)