iOS 7 iPad Safari Landscape innerHeight / outerHeight проблема макета



мы видим проблемы с веб-приложением, которое имеет высоту 100% на Safari в iOS 7. Оказывается, что окно.innerHeight (672px) не соответствует окну.outerHeight (692px), но только в ландшафтном режиме. В конечном итоге происходит то, что в приложении со 100% высотой на теле вы получаете 20px дополнительного пространства. Это означает, что когда пользователь пролистывает наше приложение, элементы навигации подтягиваются за браузер chrome. Это также означает, что любые абсолютно позиционированные элементы, которые находятся внизу из экрана в конечном итоге 20px выкл.

эта проблема также была изложена в этом вопросе здесь: IOS 7-css-html высота-100% = 692px

и можно увидеть на этом неоднозначном скриншоте: iOS 7 Safari outerHeight issue

то, что мы пытаемся сделать, - это взломать это, чтобы до тех пор, пока Apple не исправит ошибку, нам не нужно беспокоиться об этом.

один из способов сделать это-абсолютно позиционировать тело только в iOS 7, но это в значительной степени ставит дополнительные 20px в верхней части страница вместо нижней:

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

любая помощь в том, чтобы заставить outerHeight соответствовать innerHeight или взломать его, чтобы наши пользователи не могли видеть эту проблему, была бы очень признательна.

182   13  

13 ответов:

в моем случае решение состояло в том, чтобы изменить позиционирование на фиксированное:

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

Я также использовал скрипт для обнаружения iPad с iOS 7:

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

простой, чистый CSS-только решение:

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

iOS 7, кажется, правильно установить высоту с этим. Также нет необходимости изменять размер событий javascript и т. д. Поскольку вы работаете с приложением полной высоты, на самом деле не имеет значения, всегда ли оно фиксировано.

ответ Сэмюэля, Как также заявил Терри Торсен, отлично работает, но терпит неудачу в случае, если веб-страница была добавлена в iOS home.

более интуитивным решением было бы проверить window.navigator.standalone var.

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

таким образом, он применяется только при открытии внутри Safari, а не при запуске из дома.

ответ Сэмюэля является лучшим, хотя он ломается, если пользователь добавляет страницу на свой домашний экран (страницы домашнего экрана не показывают ошибку). Проверьте 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)";
}

вариант подхода Сэмюэля, но с позицией: - webkit-sticky set на html работал для меня лучше всего.

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

обратите внимание 'top: 0', а не' bottom: 0', а целевой элемент - 'html', а не'body'

в основном есть две ошибки-высота окна в ландшафтном режиме и положение прокрутки, когда пользователь перематывает его из портретного режима. Мы решили это так:

высота окна контролируется:

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

вам нужен 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();
});

Вам также нужно установить position: fixed на <body>.

вот полный, рабочий пример:

<!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-элемента "под" фиксированным элементом тела.

Если я использую это:

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

мой Safari на Mac показывает те же классы 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;
   }
}

///// С этим вы более гибкие или другие ОС и браузеры

я наткнулся на эту страницу по той же проблеме. Здесь есть много полезных ответов, а другие нет (для меня).

тем не менее, я нашел решение, которое работает в моем случае, и работает полностью независимо от того, какая версия ОС и какая ошибка сейчас или в прошлом или будущем.

объяснение: Разработка веб-приложения (без собственного приложения) с несколькими модулями фиксированного размера в полноэкранном режиме, с именем класса "модуль"

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

, который содержит нижний колонтитул с именем класса "нижний колонтитул"

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

благодаря навыкам Маттео Спинелли я все еще могу использовать iScroll без проблем, так как его события изменения, к счастью, уволены после. Если нет, то необходимо будет снова вспомнить iScroll-init после исправления.

надеюсь, что это поможет кому-то

принятый ответ не справляется, когда отображается панель избранного. Вот улучшен улов все исправить:

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

что делать, если вы попробуете

html{ bottom: 0;padding:0;margin:0}body {
position: absolute;
bottom: 0;
height: 672px !important;
}
    Ничего не найдено.

Добавить ответ:
Отменить.