Серая область видима при переключении с портрета на пейзаж с использованием iOS 7.1 минимального ui

В веб-приложении, над которым я работаю, я попробовал новую функцию minimal-ui для iOS 7.1 (см. полноэкранный режим Safari в iOS 7.1 с мета-тегом с минимальным уровнем ui), но я вижу проблему, когда серая область 84px-high появляется внизу, когда я переключаюсь с портрета на пейзаж. Кроме того, document.body.scrollTop изменяется на 64 после переключения на альбомный.

Вы можете увидеть проблему, используя это веб-приложение "Hello World" : http://www.creativepulse.gr/media/blog/2014/20140123-hello-world/example.html

Когда я загружаю приложение в Mobile Safari на iOS 7.1 iPhone Retina Simulator, все в порядке в портретном режиме. Однако, переключаясь на пейзаж, сразу появляется серая область.

Каков хороший способ решить эту проблему?

Ответы

Ответ 1

Прокрутка вверху после того, как страница оказала мне помощь, помогла мне. Это почему-то вызывает реинжиниринг, а серая коробка исчезает, однако я не могу объяснить, что именно делает Safari внутри:

window.scrollTo(0, 0);

Ответ 2

Я пытался какое-то время исправить это без везения. Я, наконец, решил провести тест, где я:

  • Создал новый HTML-документ с метатегом minimal-ui.
  • Оставил тело документа пустым (без HTML-тегов) и никаких стилей.

Протестировано, и проблема все еще возникает.

Единственный вывод, который я мог придумать, - это ошибка в IOS 7.1, поэтому я отправил отчет об ошибке Apple. Сообщается как BUG #: 16335579.

Обратите внимание, что Mr. Решение kraftwer1 работало для меня (это взломать, но придется делать, пока Apple не установит это). То есть добавление... window.scrollTo(0, 0); после orientationChange работает.

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

Ответ 3

Проблема действительно кажется ошибкой в ​​iOS 7.0 и 7.1 до сих пор. Я смог воспроизвести его только при использовании устройства в ландшафте.

Это происходит в трех ситуациях, о которых я знаю, и во всех случаях хакер window.scrollTo(0, 0) разрешает его.

  • При вращении устройства в ландшафт. Может быть разрешено с помощью:

    $(window).on('orientationchange', function () {
      window.scrollTo(0, 0);
    });
    
  • При перетаскивании снизу документа. Разрешено обработкой события scroll:

    $(window).on('scroll', function () {
      var focusedElement;
    
      if ($(document).scrollTop() !== 0) {
        focusedElement = $(':focus');
        if (!(focusedElement.is('input') || focusedElement.is('textarea'))) window.scrollTo(0, 0);
      }
    });
    

    Исключения для сфокусированных элементов необходимы, потому что, когда открывается экранная клавиатура, она также вызывает событие прокрутки в окне.

  • При закрытии клавиатуры - все элементы теряют фокус:

    formLayer.on('blur', 'input, textarea', function () {
      if (!$(':focus').length) window.scrollTo(0, 0);
    });
    

Поскольку эта проблема относится только к версиям iOS версии 7.0 и 7.1, лучше ограничить этот взлом следующим выражением:

var buggyIOS = /\b(?:iPhone|iPod|iPad).*?\bOS 7_[01]/.test(window.navigator.userAgent);

Ответ 4

Усовершенствование решения window.scrollTo(0,0), я инкапсулирую в самоописывающееся сразу вызываемое выражение функции и выполняю на готовом документе и изменяя размер окна:

(function minimalUiFix() {
  var fix = function () {
    window.scrollTo(0,0);
  };

  $(fix);
  $(window).on('resize.minimal-ui-fix', fix);
})();

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

Там много чего происходит, но я использую его в jsbin.

Этот трюк, похоже, не делает трюк для меня. Проверьте jsbin. То, что у меня здесь, довольно просто: контейнер с фиксированной позицией с переполнением, который должен занимать весь экран. Прокрутка не должна быть возможной, однако, я все еще получаю какое-то непреднамеренное прокручиваемое пространство. Весь этот трюк - это прокрутка назад. Это не устраняет таинственное дополнительное пространство, которое вызывает настоящую проблему.

Но, применяя исправление на свитке в дополнение к готовому и изменяемому размеру, кажется, будет ближе всего к достойной работе вокруг, которую я мог найти.

(function minimalUiFix() {

  var fix = function () { window.scrollTo(0,0); };
  $(fix);
  $(window).on('resize.minimal-ui-fix', fix);
  $(window).on('scroll.minimal-ui-fix', fix);

})();

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

Ответ 5

Самое лучшее исправление, которое я нашел, - здесь от Александра Коледы.

window.addEventListener('scroll', function () {
    if (document.activeElement === document.body && window.scrollY > 0) {
        document.body.scrollTop = 0;
    }
}, true);

Это также фиксирует серое полотно при прокрутке вниз.

Ответ 6

<meta name="viewport" content="width=device-width, initial-scale=1, minimal-ui=1, user-scalable=no">

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

<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">

Ответ 7

Я читал это сообщение, пытаясь избежать той же проблемы и нашел другой способ сделать это.

Сначала давайте обнаружим, если устройство повернуто (также мы можем обнаружить позже, если это портрет или пейзаж), для этого я собираюсь настроить var для проверки медиа-запросов из JS:

var mql = window.matchMedia("(orientation: portrait)");

Затем мы можем прослушать, если есть какие-либо изменения и переписать видовое окно:

    mql.addListener(function(m) {
        $('meta[name="viewport"]').attr("content","width=device-width, user-scalable=no, maximum-scale=1.2"); // No matter if is landscape or portrait
    });

Или мы можем быть более конкретными и запускать что-то другое для пейзажа/портрета

    mql.addListener(function(m) {
        if(m.matches) {
            $('meta[name="viewport"]').attr("content","width=device-width, user-scalable=no, maximum-scale=1.2"); // Portrait
        }
        else {
            $('meta[name="viewport"]').attr("content","width=device-width, user-scalable=no, maximum-scale=1.0"); // Landscape
        }
    }); 

Надеюсь, это поможет вам!