IOS7 iPad Safari 风景内外高度布局问题

我们看到一个网络应用程序在 iOS7中的 Safari 高度为100% 时出现了问题。似乎 window.innerHeight (672px)与 window.outerHeight (692px)不匹配,但只在横向模式下匹配。最后发生的是,在一个应用程序100% 的身高,你得到20像素的额外空间。这意味着当用户在我们的应用程序上滑动时,导航元素会被拉到浏览器 Chrome 后面。这也意味着,任何绝对定位的元素,在屏幕底部结束了20像素关闭。

这个问题也概述了这个问题: IOS 7-css-html 高度-100% = 692px

从这张模棱两可的截图中可以看出: iOS 7 Safari outerHeight issue

我们要做的就是破解这个漏洞,这样在苹果修复这个漏洞之前,我们就不用担心了。

这样做的一个方法就是只在 iOS7中放置正文,但是这样做会把额外的20px 放在页面的顶部而不是底部:

body {
position: absolute;
bottom: 0;
height: 672px !important;
}

如果您能提供帮助,强制 outHeight 与 innerHeight 匹配,或者对其进行修改,以便我们的用户看不到这个问题,我们将不胜感激。

42868 次浏览

如果你试试呢

html{ bottom: 0;padding:0;margin:0}body {
position: absolute;
bottom: 0;
height: 672px !important;
}

在我的例子中,解决方案是将定位改为固定:

@media (orientation:landscape) {
html.ipad.ios7 > body {
position: fixed;
bottom: 0;
width:100%;
height: 672px !important;
}
}

我还使用了一个脚本来检测 iOS7中的 iPad:

if (navigator.userAgent.match(/iPad;.*CPU.*OS 7_\d/i)) {
$('html').addClass('ipad ios7');
}

基本上有两个错误-窗口的高度在横向模式和滚动的位置时,用户回到它从纵向模式。我们是这样解决的:

窗口的高度由以下因素控制:

// window.innerHeight is not supported by IE
var winH = window.innerHeight ? window.innerHeight : $(window).height();


// set the hight of you app
$('#yourAppID').css('height', winH);


// scroll to top
window.scrollTo(0,0);

现在,可以将上述内容放入函数中,并绑定到窗口调整大小和/或方向更改事件。就是这样... 看例子:

Http://www.ajax-zoom.com/examples/example22.php

Samuel 的回答是最好的,尽管如果用户将页面添加到他们的主屏幕(主屏幕页面不会显示错误) ,那么它就会崩溃。在添加类之前检查 innerHeight,如下所示:

if (navigator.userAgent.match(/iPad;.*CPU.*OS 7_\d/i)) {
if(window.innerHeight==672){
$('html').addClass('ipad ios7');
}
}

请注意,该错误也不会在 webview 下显示。

我使用这个 JavaScript 解决方案来解决这个问题:

    if (navigator.userAgent.match(/iPad;.*CPU.*OS 7_\d/i) && window.innerHeight != document.documentElement.clientHeight) {
var fixViewportHeight = function() {
document.documentElement.style.height = window.innerHeight + "px";
if (document.body.scrollTop !== 0) {
window.scrollTo(0, 0);
}
}.bind(this);


window.addEventListener("scroll", fixViewportHeight, false);
window.addEventListener("orientationchange", fixViewportHeight, false);
fixViewportHeight();


document.body.style.webkitTransform = "translate3d(0,0,0)";
}

塞缪尔的回答,也由特里索尔森表示,是工作良好,但失败的情况下,网页已被添加到 iOS 的主页。

更直观的修复方法是检查 window.navigator.standalone变量。

if (navigator.userAgent.match(/iPad;.*CPU.*OS 7_\d/i) && !window.navigator.standalone) {
$('html').addClass('ipad ios7');
}

这种方法只适用于在 Safari 内部打开的情况,而不适用于从家里启动的情况。

您需要 JavaScript 来解决这个 bug。window.innerHeight具有正确的高度。这是我能想到的最简单的解决办法:

$(function() {
function fixHeightOnIOS7() {
var fixedHeight = Math.min(
$(window).height(), // This is smaller on Desktop
window.innerHeight || Infinity // This is smaller on iOS7
);
$('body').height(fixedHeight);
}


$(window).on('resize orientationchange', fixHeightOnIOS7);
fixHeightOnIOS7();
});

您还需要在 <body>上设置 position: fixed

下面是一个完整的、可行的例子:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<title>iOS7 height bug fix</title>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script>
$(function() {
function fixHeightOnIOS7() {
var fixedHeight = Math.min(
$(window).height(),
window.innerHeight || Infinity
);
$('body').height(fixedHeight);
}


$(window).on('resize orientationchange', fixHeightOnIOS7);
fixHeightOnIOS7();


// Generate content
var contentHTML = $('#content').html();
for (var i = 0; i < 8; i++) contentHTML += contentHTML;
$('#content').html(contentHTML);
});
</script>
<style>
html,
body
{
margin: 0;
padding: 0;
height: 100%;
width: 100%;
overflow: auto;
position: fixed;
}
#page-wrapper
{
height: 100%;
position: relative;
background: #aaa;
}
#header,
#footer
{
position: absolute;
width: 100%;
height: 30px;
background-color: #666;
color: #fff;
}
#footer
{
bottom: 0;
}
#content
{
position: absolute;
width: 100%;
top: 30px;
bottom: 30px;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
</style>
</head>
<body>
<div id="page-wrapper">
<div id="header">Header</div>
<div id="content">
<p>Lorem ipsum dolor sit amet.</p>
</div>
<div id="footer">Footer</div>
</div>
</body>
</html>

关于已被接受的答案,我还有以下规则:

html.ipad.ios7 {
position: fixed;
width: 100%;
height: 100%;
}

这样做还有一个好处,就是可以停止 html 元素在固定 body 元素下滚动。

简单,清洁的 CSS-唯一的解决方案:

html {
height: 100%;
position: fixed;
width: 100%;
}

IOS7似乎用这个设置了正确的高度。也没有必要调整 javascript 事件的大小,等等。 因为你使用的是一个全高应用程序,所以它是否总是位置固定并不重要。

如果我用这个:

if (navigator.userAgent.match(/iPad;.*CPU.*OS 7_\d/i) && !window.navigator.standalone) {
$('html').addClass('ipad ios7');
}

我在 Mac 上的 Safari 显示了相同的 html 类... ... 所以它不能正常工作。

我尝试了结合一些事情-这对我来说工作,所以我可以管理它在浏览器和没有浏览器视图。

JQuery

if (navigator.userAgent.match(/iPad/i) && (window.orientation) ){
$('html').addClass('ipad ');
if (window.innerHeight !=  window.outerHeight ){
$('html').addClass('browser  landscape');
}
else{
$('html').addClass('browser portrait');
}
}

CSS

@media (orientation:landscape) {
html.ipad.browser > body {
position: fixed;
height: 671px !important;
}
}

有了这个,你可以更灵活地使用其他操作系统和浏览器

我看到这一页是为了同一个问题。 这里有很多有用的答案,其他的(对我来说)没有。

然而,我找到了一个解决方案,它在我的案例中起作用,并且完全独立于现在或过去或将来的操作系统版本和 bug。

说明: 开发一个网络应用程序(没有本地应用程序)与几个固定大小的全屏模块,类名为“模块”

.module {position:absolute; top:0; right:0; bottom:0; left:0;}

其中包含一个类名为“ footer”的页脚

.module > .footer {position:absolute; right:0; bottom:0; left:0; height:90px;}

没关系,如果我稍后将页脚的高度设置为另一个高度,或者甚至它的高度是由其内容设置的,我可以使用以下代码进行修正:

function res_mod(){
$('.module').css('bottom', 0); // <-- need to be reset before calculation
var h = $('.module > .footer').height();
var w = window.innerHeight;
var o = $('.module > .footer').offset();
var d = Math.floor(( w - o.top - h )*( -1 ));
$('.module').css('bottom',d+'px'); // <--- this makes the correction
}


$(window).on('resize orientationchange', res_mod);


$(document).ready(function(){
res_mod();
});

由于 Matteo Spinelli 的技能,我仍然可以毫无问题地使用 iScroll,因为它的更改事件幸运地在更改之后触发。如果没有,则需要在更正之后再次召回 iScroll-init。

希望这对谁有帮助

Samuel 的方法的一个变体,但是位置:-webkit- html 上的粘性设置对我来说效果最好。

@media (orientation:landscape) {
html.ipad.ios7 {
position: -webkit-sticky;
top: 0;
width: 100%;
height: 672px !important;
}
}

注意‘ top: 0’,而不是‘ bottom: 0’,目标元素是‘ html’,而不是‘ body’

当收藏栏显示时,已接受的答案无法处理。以下是改进后的补丁:

@media (orientation:landscape) {
html.ipad.ios7 > body {
position: fixed;
height: calc(100vh - 20px);
width:100%;
}
}