iOS 7 iPad Safari Liggend innerHeight/outerHeight lay-outprobleem

We zien problemen met een web-app met een hoogte van 100% in Safari in iOS 7. Het lijkt erop dat de window.innerHeight (672px) niet overeenkomt met window.outerHeight (692px), maar alleen in landscape modus. Wat er uiteindelijk gebeurt, is dat je in een app met 100% hoogte op het lichaam 20px extra ruimte krijgt. Dit betekent dat wanneer een gebruiker omhoog veegt in onze app, de navigatie-elementen achter het chroom van de browser worden getrokken. Het betekent ook dat alle absoluut gepositioneerde elementen die zich onder aan het scherm bevinden 20px afwijken.

Dit probleem werd hier ook in deze vraag beschreven:
IOS 7 – css – html hoogte – 100% = 692px

En is te zien in deze dubbelzinnige screenshot:
iOS 7 Safari outerHeight-probleem

We proberen dit te omzeilen, zodat we ons er geen zorgen over hoeven te maken totdat Apple de bug heeft opgelost.

Een manier om dit te doen is om de body absoluut alleen in iOS 7 te positioneren, maar dit plaatst de extra 20px vrijwel bovenaan de pagina in plaats van onderaan:

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

Elke hulp bij het forceren van outerHeight zodat het overeenkomt met innerHeight, of er omheen hacken zodat onze gebruikers dit probleem niet kunnen zien, wordt zeer op prijs gesteld.


Antwoord 1, autoriteit 100%

In mijn geval was de oplossing om de positionering te veranderen in vast:

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

Ik heb ook een script gebruikt om iPad te detecteren met iOS 7:

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

Antwoord 2, autoriteit 27%

Eenvoudige, schonere oplossing met alleen CSS:

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

iOS 7 lijkt hiermee de hoogte correct in te stellen. Het is ook niet nodig om de grootte van javascript-gebeurtenissen, enz.
Aangezien u met een app op volledige hoogte werkt, maakt het niet echt uit of deze altijd een vaste positie heeft.


Antwoord 3, autoriteit 23%

Samuel’s antwoord, zoals ook aangegeven door Terry Thorsen, werkt prima, maar mislukt als de webpagina is toegevoegd aan de iOS-homepage.

Een meer intuïtieve oplossing zou zijn om te controleren op window.navigator.standalonevar.

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

Op deze manier is het alleen van toepassing wanneer het wordt geopend in Safari, en niet als het vanuit huis wordt gestart.


Antwoord 4, autoriteit 3%

Samuel’s antwoord is het beste, hoewel het breekt als een gebruiker de pagina aan zijn startscherm toevoegt (startschermpagina’s vertonen de bug niet). Controleer de innerHeight voordat u de klas toevoegt, zoals:

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

Merk op dat de bug ook niet wordt weergegeven onder webview.


Antwoord 5, autoriteit 3%

Ik heb deze JavaScript-oplossing gebruikt om dat probleem op te lossen:

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

Antwoord 6, autoriteit 2%

Een variant van Samuel’s aanpak, maar met positie: -webkit-sticky ingesteld op html werkte voor mij het beste.

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

Let op ‘top: 0’, niet ‘bottom: 0’, en doelelement is ‘html’, niet ‘body’


Antwoord 7

Er zijn in principe twee fouten: de hoogte van het venster in de liggende modus en de schuifpositie wanneer de gebruiker ernaar terugkeert vanuit de portretmodus. We hebben het op deze manier opgelost:

de hoogte van het raam wordt bepaald door:

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

nu kan het bovenstaande in een functie worden geplaatst en binden aan venstergrootte en/of oriëntatieveranderingsgebeurtenissen. dat is het… zie voorbeeld:

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


Antwoord 8

Je hebt JavaScript nodig om deze bug te omzeilen. window.innerHeightheeft de juiste hoogte. Dit is de eenvoudigste oplossing die ik kan bedenken:

$(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();
});

Je moet ook position: fixedinstellen op de <body>.

Hier is een compleet, werkend voorbeeld:

<!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="https://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>

Antwoord 9

wat als je het probeert

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

Other episodes