IOS 7 iPad Safari Пейзаж innerHeight/внешний дизайн макета

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

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

И можно увидеть в этом двусмысленном скриншоте: iOS 7 Safari outerHeight issue

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

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

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

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

Ответ 1

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

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

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

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

Ответ 2

Простое, чистое решение только для CSS:

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

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

Ответ 3

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

Более интуитивно понятное исправление будет проверять на window.navigator.standalone var.

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

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

Ответ 4

Ответ Samuel - лучший, хотя он ломается, если пользователь добавляет страницу на свой домашний экран (на главном экране страницы не отображается ошибка). Проверьте значение innerHeight перед добавлением класса следующим образом:

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

Обратите внимание, что ошибка также не отображается в webview.

Ответ 5

Я использовал это решение 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)";
}

Ответ 6

Вариант подхода Сэмюэла, но с положением: -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"

Ответ 7

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

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

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

Ответ 8

Вам нужно 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>

Ответ 9

Что касается принятого ответа, мне также повезло со следующим правилом:

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

Это имеет дополнительное преимущество в том, что он, кажется, останавливает элемент html, прокручивая "под" фиксированный элемент тела.

Ответ 10

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

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

Мой Safari на Mac показывает те же классы html... SO его работает некорректно.

Я попытался объединить несколько вещей - это сработало для меня, поэтому я могу управлять им в браузере и без просмотра браузера.

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

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

Ответ 11

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

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

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

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

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

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

Nevermind, если я установил высоту нижнего колонтитула позже на другую высоту или даже ее высоту установил по содержанию, я могу использовать этот следующий код для исправления:

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 после коррекции.

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

Ответ 12

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

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

Ответ 13

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

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