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

В веб-приложении, над которым я работаю, я опробовал новую функцию minimal-ui iOS 7.1 (см. Полноэкранный режим Safari в iOS 7.1 с метатегом Minimal-UI), но я вижу проблему, из-за которой внизу появляется серая область высотой 84 пикселя, когда я переключаюсь с портрет в пейзаж. Кроме того, 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, в портретном режиме все нормально. Однако при переключении в ландшафт сразу появляется серая область.

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


person Daniel Trebbien    schedule 13.03.2014    source источник
comment
Не могли бы вы прикрепить скриншоты? Я думаю, что у меня может быть такая же проблема, но я хочу подтвердить.   -  person Stoutie    schedule 09.09.2014
comment
это то, как это выглядит? Скриншот из моего jsbin.   -  person Stoutie    schedule 09.09.2014
comment
@stoutie: Да, это так.   -  person Daniel Trebbien    schedule 09.09.2014


Ответы (7)


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

window.scrollTo(0, 0);
person kraftwer1    schedule 23.03.2014
comment
Это лишь временно устраняет проблему. Страница по-прежнему прокручивается ниже нижней части с включенным minimal-ui. CSS для html или body для предотвращения переполнения тоже ничего не делает. - person maxkfranz; 04.07.2014
comment
Смотрите обновление моего ответа ниже. Я связал jsbin, который показывает, что проблема все еще существует. - person Stoutie; 11.09.2014

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

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

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

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

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

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

person goldj930    schedule 15.03.2014
comment
Спасибо, что проверили это и отправили отчет об ошибке. Я тоже пробовал кое-что, чтобы решить эту проблему, но мои попытки не решили проблему и привели к еще более серьезным проблемам, таким как отключение событий на те же 84 пикселя. - person Daniel Trebbien; 16.03.2014
comment
Без проблем. Надеемся, что команда Apple QA наклонит свой телефон в альбомную ориентацию, прежде чем выпустить такую ​​​​важную функцию в будущих выпусках. - person goldj930; 18.03.2014
comment
Спасибо, у меня тоже есть эта проблема здесь. Можно ли где-то увидеть ваш пост для обновления? - person Dafen; 24.03.2014
comment
@ goldj930, где вы отправляете отчеты об ошибках для Mobile Safari? Мне нужно представить довольно много! (переполнение: авто, -webkit-overflow-scrolling: сенсорный, минимальный интерфейс и т. д.). Это был кошмар, пытаясь умилостивить богов мобильного сафари. Я готов пожертвовать ребенком. - person Stoutie; 09.09.2014
comment
У меня тоже такая проблема с iOS 8.4 - person dude; 22.10.2015

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

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

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

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

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

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

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

    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);
person Alvaro    schedule 14.08.2014

Усовершенствуя решение 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 или не будет обнаружен другой обходной путь.

person Stoutie    schedule 09.09.2014

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

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

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

person Sarah-Jane    schedule 24.08.2014
comment
Это полностью глючит, прокручивается сверху каждый раз, когда пользователь пытается прокручивать пальцем. - person Julian Xhokaxhiu; 28.10.2014

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

Просто удалите Minimal-UI, который избавил меня от него.

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

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

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

Я надеюсь, что это может помочь вам!

person DD.    schedule 14.04.2014
comment
Я не думал, что можно будет изменить метатеги после загрузки? - person Burgi; 03.06.2014
comment
Просто попробуйте... это то, что я использую в своих проектах, и это работает довольно хорошо. - person DD.; 04.06.2014
comment
Лучший код — это код без каких-либо объяснений. Бог знает, почему вы связываетесь с максимальным масштабом. - person Ben Affleck; 27.10.2014