ChatGPT解决这个技术问题 Extra ChatGPT

iOS 7 iPad Safari Landscape innerHeight/outerHeight 布局问题

我们在 iOS 7 的 Safari 上看到高度为 100% 的 Web 应用程序存在问题。window.innerHeight (672px) 似乎与 window.outerHeight (692px) 不匹配,但仅在横向模式下。最终发生的情况是,在一个身体高度为 100% 的应用程序中,您将获得 20 像素的额外空间。这意味着当用户在我们的应用程序上向上滑动时,导航元素会被拉到浏览器 chrome 后面。这也意味着位于屏幕底部的任何绝对定位元素最终都会偏离 20 像素。

此处的问题中也概述了此问题:IOS 7 - css - html height - 100% = 692px

https://i.stack.imgur.com/VPQYy.png

我们正在尝试做的是解决这个问题,以便在 Apple 修复错误之前,我们不必担心它。

这样做的一种方法是仅在 iOS 7 中绝对定位正文,但这几乎会将额外的 20px 放在页面顶部而不是底部:

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

任何有关强制 outerHeight 匹配 innerHeight 或绕过它以使我们的用户看不到此问题的帮助将不胜感激。

有关详细信息,请参阅此 URL:krpano.com/ios/bugs/ios7-ipad-landscape
附带说明:此错误似乎已在 iOS8 上修复。变通办法应该只针对 iOS7。

S
Samuel Moreno López

就我而言,解决方案是将定位更改为固定:

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

我还使用了一个脚本来检测带有 iOS 7 的 iPad:

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

我将此与在方向更改上执行 window.scrollTo(0,0); 结合起来,它似乎解决了我们 99% 的问题。给我几天在生产中使用它,我想我们可能会有答案。
刚发现有朋友用 iPad mini OS 7 没有这个问题,不知道是不是 iPad mini?
我有一个带视网膜的 iPad mini 并看到同样的问题
哇......我不敢相信我花了这么长时间才找到这个。我整晚都在寻找几乎但从未奏效的奇怪的javascript hacks。这真太了不起了。
OMG 在 ipad sim 上浪费了大约两天时间,想着我的立场:绝对;正在处理这个问题。谢谢!
m
mikeStone

简单、干净的纯 CSS 解决方案:

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

iOS 7 似乎用这个正确设置了高度。也不需要调整 javascript 事件的大小等。由于您正在使用全高应用程序,因此它是否始终固定位置并不重要。


奇怪的是,这适用于配备 Retina 的普通 iPad,但不适用于 iPad Mini。 672px 修复似乎对两者都有效。
A
Andrea Tondo

正如 Terry Thorsen 所说,Samuel 的回答效果很好,但如果网页已添加到 iOS 主页,则会失败。

更直观的解决方法是检查 window.navigator.standalone var。

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

这样,它仅适用于在 Safari 中打开时,而不是从家中启动时。


另一种不起作用的情况是显示收藏夹栏时。因此,有了这个答案和我的下面-涵盖了所有问题(据我所知!)
T
Terry Thorsen

塞缪尔的答案是最好的,尽管如果用户将页面添加到他们的主屏幕(主屏幕页面不显示错误),它会中断。在添加类之前检查 innerHeight ,如下所示:

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

请注意,该错误也不会出现在 webview 下。


我的 iPad 报告 window.innerHeight 为 671(带有 console.log),因此 672 并不总是准确的。
c
czuendorf

我使用这个 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)";
}

o
overmailed

Samuel 方法的一种变体,但 position: -webkit-sticky 在 html 上设置对我来说效果最好。

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

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


V
Vadim

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

窗口的高度由以下控制:

// 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


您实际上并没有解决问题,因为页面底部有一个奇怪的空白(看 here),用户仍然可以滚动页面。
a
andraaspar

您需要 JavaScript 来解决此错误。 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>

N
Nick Maynard

参考接受的答案,我也很幸运遵循以下规则:

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

这具有额外的优势,因为它似乎停止了 html 元素在固定主体元素“下方”滚动。


E
Excellll

如果我使用这个:

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;
   }
}

///// 有了这个你更灵活或其他操作系统和浏览器


d
ddlab

我遇到了这个页面同样的问题。这里有很多有用的答案,而其他的则没有(对我而言)。

但是,我找到了一个解决方案,它适用于我的情况,并且完全独立于现在、过去或将来的哪个操作系统版本和哪个错误。

说明:开发一个全屏具有多个固定大小模块的 Web 应用程序(非本机应用程序),类名称为“模块”

.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。

希望这可以帮助某人


N
Nick Hingston

当收藏夹栏显示时,接受的答案无法应对。这是改进的全部修复:

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

a
ainos

如果你尝试怎么办

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