2013-09-25 2 views
72

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

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

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

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

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

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

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

+2

для более подробно передать этот URL: http://krpano.com/ios/bugs/ios7-ipad-landscape/ –

+1

На стороне записки: это ошибка, кажется, исправлено на iOS8. Обходные пути должны ориентироваться только на iOS7. –

ответ

60

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

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

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

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

Я объединил это с выполнением 'window.scrollTo (0,0);' изменения ориентации и, похоже, решил 99% наших проблем. Дайте мне пару дней использования этого в производстве, и я думаю, что у нас может быть наш ответ. – hisnameisjimmy

+1

+1, хотя я не совсем понимаю, почему это работает. – schellmax

+0

Я только что нашел, что у друга с iPad mini OS 7 нет этой проблемы, есть идея найти iPad iPad? – Gino

-1

что, если вы пытаетесь

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

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

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

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

+0

На самом деле вы не решаете проблему, потому что в нижней части страницы есть странное пустое пространство (смотрите [здесь] (http://gudulin.com/web/stackoverflow/19012135/ajax-zoom.png)) и пользователь все еще может прокручивать страницу. – agudulin

2

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

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

Обратите внимание, что ошибка не обладает также под WebView.

+2

Мой iPad сообщает window.innerHeight из 671 (с console.log), поэтому 672 не всегда точна. – Esger

2

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

ответ Самуила, а также заявил Терри Торсен, работает прекрасно, но терпит неудачу в случае веб-страница была добавлена ​​к дому IOS.

Более интуитивно понятным решением будет проверка на наличие window.navigator.standalone var.

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

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

+0

другая ситуация это не работает, когда отображается панель избранного. Таким образом, с этим ответом и моим реком - все вопросы были рассмотрены (насколько я знаю!) –

0

Для этого вам нужен 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> 
0

Со ссылкой на принятый ответ, я также имел удачи со следующим правилом:

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

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

16

Простой, уборщик CSS-единственное решение:

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

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

+0

Это работает на обычном iPad с сетчаткой, но не работает на iPad Mini, как ни странно. Исправление 672px, похоже, работает на обоих. – jscharf

0

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

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

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

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

0

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

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

Explaination: Developping веб-приложение (не родное приложение) с несколькими модулями фиксированного размера в полноэкранном режиме, с именем класса «модуль»

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

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

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

Надеется, что это помогает кому-то

1

Вариации подхода Самуила, но с позицией: -webkit-липкий набор на HTML работает для меня лучше всего.

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

Примечание «верх: 0», а не «Дно: 0», а целевой элемент «HTML», а не «тело»

0

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

@media (orientation:landscape) { 
    html.ipad.ios7 > body { 
    position: fixed; 
    height: calc(100vh - 20px); 
    width:100%; 
    } 
} 
Смежные вопросы