IOS 8 удалил свойство "minimum-ui" viewport, существуют ли другие "мягкие полноэкранные" решения?

(Это многочастный вопрос, я постараюсь изо всех сил суммировать сценарий.)

В настоящее время мы создаем отзывчивое веб-приложение (средство чтения новостей), которое позволяет пользователям прокручивать содержимое с вкладками, а также прокручивать по вертикали внутри каждого содержимого с вкладками.

Общим подходом к проблеме является наличие оболочки div, которая заполняет окно просмотра браузера, устанавливает overflow на hidden или auto, а затем прокручивается по горизонтали и/или вертикально внутри него.

Этот подход замечательный, но имеет один главный недостаток: , так как высота документа точно такая же, как и окно просмотра браузера, мобильный браузер не будет скрывать адресную строку/меню навигации.. p >

многочисленные хаки и свойства видового экрана, которые позволяют нам получать больше экранной недвижимости, но ни один из них не столь эффективен, как minimal-ui ( введенный в iOS 7.1).

Вчера появились новости о том, что iOS 8 beta4 удалил minimal-ui из Mobile Safari (см. раздел Webkit в Примечания к выпуску iOS 8), который оставил нам интересно:

Q1. Можно ли скрыть адресную строку в Mobile Safari?

Насколько нам известно, iOS 7 больше не отвечает на window.scrollTo хак, это говорит о том, что нам нужно жить с меньшим экраном если мы не примем вертикальный макет или не используем mobile-web-app-capable.

Q2. Возможно ли иметь аналогичный мягкий полноэкранный режим?

Мягким полноэкранным экраном я действительно подразумеваю без использования метатега mobile-web-app-capable.

Наше веб-приложение построено так, чтобы быть доступным, любая страница может быть помечена закладкой или разделена с использованием собственного меню браузера. Добавляя mobile-web-app-capable, мы запрещаем пользователям вызывать такое меню (когда оно сохраняется на рабочем столе), что смущает и антагонизирует пользователей.

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

Q3. Стоит ли работать с полноэкранным режимом?

Казалось бы, API fullscreen API не придет в iOS в ближайшее время, но даже если это так, я не вижу, как меню будет оставаться доступным (то же самое касается Chrome на Android).

В этом случае, возможно, нам стоит просто оставить мобильное сафари в том виде, в каком оно есть, и учитывать высоту видового экрана (для iPhone 5+, это 460 = 568 - 108, где 108 включает панель ОС, адресную строку и меню навигации; iPhone 4 или старше, это 372).

Хотелось бы услышать некоторые альтернативы (помимо создания собственного приложения).

Ответ 1

Свойство минимального ui viewport больше не поддерживается в iOS 8. Однако сам минимальный ui не исчез. Пользователь может ввести минимальный ui с жестом "touch-drag down".

Существует несколько предварительных условий и препятствий для управления состоянием представления, например. для работы с минимальным уровнем ui должно быть достаточно контента, чтобы пользователь мог прокручивать; для сохранения минимального значения ui, прокрутка окна должна быть смещена при загрузке страницы и после изменения ориентации. Тем не менее, нет способа вычисления размеров минимального-ui с использованием переменной screen, и, таким образом, не указывается, когда пользователь находится в минимальном ui заранее.

Эти наблюдения являются результатом исследования как части разработки Brim-view manager для iOS 8. Конечная реализация работает следующим образом:

Когда страница загружена, Brim создаст элемент беговой дорожки. Элемент Treadmill используется для прокрутки пользовательского пространства. Присутствие элемент беговой дорожки гарантирует, что пользователь может ввести минимальный вид и что он продолжает сохраняться, если пользователь перезагружает страницу или изменяет ориентация устройства. Он невидим для пользователя все время. Эта элемент имеет идентификатор brim-treadmill.

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

Когда страница находится в минимальном ui, Brim отключит прокрутку документ (он делает это в безопасном путь, который не влияет на содержимое основного элемента). Отключение прокрутки документа предотвращает случайное отключение минимального ui при прокрутке вверх. Согласно оригинальной спецификации iOS 7.1, нажатие верхней панели возвращает остальная часть хрома.

Конечный результат выглядит следующим образом:

Brim in iOS simulator.

Для документации и в случае, если вы предпочитаете писать свою собственную реализацию, стоит отметить, что вы не можете использовать Scream чтобы определить, находится ли устройство в минимальном ui прямо после события orientationchange, поскольку размеры window не отражают новую ориентацию до анимации вращения закончилось. Вы должны присоединить слушателя к событию orientationchangeend.

Scream и orientationchangeend были разработанной в рамках этого проекта.

Ответ 2

Поскольку нет программного способа имитации minimal-ui, мы придумали другое обходное решение, используя calc() и известную высоту адресной строки iOS в наших интересах:

Следующая демонстрационная страница (также доступна по gist, более технические данные там) предложит пользователю прокрутить, что затем запускает soft-fullscreen (скрыть адресную строку/меню), где заголовок и содержимое заполняют новое окно просмотра.

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Scroll Test</title>

    <style>
        html, body {
            height: 100%;
        }

        html {
            background-color: red;
        }

        body {
            background-color: blue;
            margin: 0;
        }

        div.header {
            width: 100%;
            height: 40px;
            background-color: green;
            overflow: hidden;
        }

        div.content {
            height: 100%;
            height: calc(100% - 40px);
            width: 100%;
            background-color: purple;
            overflow: hidden;
        }

        div.cover {
            position: absolute;
            top: 0;
            left: 0;
            z-index: 100;
            width: 100%;
            height: 100%;
            overflow: hidden;
            background-color: rgba(0, 0, 0, 0.5);
            color: #fff;
            display: none;
        }

        @media screen and (width: 320px) {
            html {
                height: calc(100% + 72px);
            }

            div.cover {
                display: block;
            }
        }
    </style>
    <script>
        var timeout;

        window.addEventListener('scroll', function(ev) {

            if (timeout) {
                clearTimeout(timeout);
            }

            timeout = setTimeout(function() {

                if (window.scrollY > 0) {
                    var cover = document.querySelector('div.cover');
                    cover.style.display = 'none';
                }

            }, 200);

        });
    </script>
</head>
<body>

    <div class="header">
        <p>header</p>
    </div>
    <div class="content">
        <p>content</p>
    </div>
    <div class="cover">
        <p>scroll to soft fullscreen</p>
    </div>

</body>
</html>

Ответ 3

Просто попрощайтесь с минимальным ui (пока)

Это правда, minimal-ui может быть полезным и вредным, и я полагаю, что компромисс теперь имеет другой баланс, в пользу более новых, больших iPhone.

Я столкнулся с проблемой при работе с моей js-инфраструктурой для приложений HTML5. После многих попыток решения, каждый из которых имел свои недостатки, я сдался с учетом того, что пространство потеряно на iPhone раньше 6. Учитывая сложившуюся ситуацию, я считаю, что единственное твердое и предсказуемое поведение является предопределенным.

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

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


ИЗМЕНИТЬ

Как я это делаю

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

html, body, #main {
  height: 100%;
  width: 100%;
  overflow: hidden;
}
.view {
  width: 100%;
  height: 100%;
  overflow: scroll;
}

Тогда:

  • то с помощью js я устанавливаю высоту #main в высоту окна. Это также помогает справляться с другими прокручивающими ошибками, обнаруженными как в iOS, так и в Android. Это также означает, что вам нужно решить, как его обновить, просто отметьте, что:

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


См. демонстрацию (на iPhone)

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

Ответ 4

Самый простой способ найти это - установить высоту тела и элементов html на 100.1% для любого запроса, где пользовательский агент был iphone. Это работает только в ландшафтном режиме, но это все, что мне нужно.

html.iphone, 
html.iphone body { height: 100.1%; }

Проверьте это на https://www.360jungle.com/virtual-tour/25

Ответ 5

Проблема с корнем здесь кажется, что сафари iOS8 не будет скрывать адресную строку при прокрутке вниз, если контент равен или меньше, чем область просмотра.

Как вы уже выяснили, добавление некоторых дополнений внизу помогает решить эту проблему:

html {
    /* enough space to scroll up to get fullscreen on iOS8 */
    padding-bottom: 80px;
}
// sort of emulate safari "bounce back to top" scroll
window.addEventListener('scroll', function(ev) {
    // avoids scrolling when the focused element is e.g. an input
    if (
        !document.activeElement
        || document.activeElement === document.body
    ) {
        document.body.scrollIntoViewIfNeeded(true);
    }
});

Вышеприведенный css должен быть условно применен, например, с использованием UN, добавляя класс gt-ios8 к <html>.

Ответ 6

Я хочу комментировать/частично отвечать/делиться своими мыслями. Я использую метод overflow-y: scroll для большого предстоящего проекта. Использование его имеет два ОСНОВНЫХ преимущества.

a) Вы можете использовать ящик с кнопками действий в нижней части экрана; если документ прокручивается, а нижняя панель исчезает, нажатие на кнопку, расположенную в нижней части экрана, сначала приведет к отображению нижней панели, а затем щелкнуть мышью. Кроме того, способ работы этой вещи вызывает проблемы с модалами, у которых есть кнопки внизу.

b) При использовании элемента overflown единственные вещи, которые были перекрашены в случае крупных изменений css, - это те, которые отображаются на экране просмотра. Это дало мне огромное повышение производительности при использовании javascript для изменения css нескольких элементов "на лету". Например, если у вас есть список из 20 элементов, которые вам нужно перекрасить, и только два из них отображаются на экране в элементе overflown, только они перекрашиваются, а остальные перекрашиваются при прокрутке. Без него все 20 элементов будут перекрашены.

.. Конечно, это зависит от проекта, и если вам нужна какая-либо функциональность, о которой я упоминал. Google использует переполненные элементы для gmail, чтобы использовать функциональные возможности, описанные в а). Imo, стоит того, даже учитывая небольшую высоту в старых iphones (372px, как вы сказали).

Ответ 7

Это возможно, используя что-то вроде приведенного ниже примера, который я собрал с помощью работы из (https://gist.github.com/bitinn/1700068a276fb29740a7), которая не совсем работала на iOS 11:

Вот модифицированный код, который работает на iOS 11.03, пожалуйста, прокомментируйте, работал ли он у вас.

Ключ добавляет некоторый размер к BODY, чтобы браузер мог прокручивать, например: height: calc (100% + 40px);

Полный образец ниже и ссылка для просмотра в вашем браузере (пожалуйста, проверьте!)

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CodeHots iOS WebApp Minimal UI via Scroll Test</title>

    <style>
        html, body {
            height: 100%;
        }
        html {
            background-color: red;
        }
        body {
            background-color: blue;
            /* important to allow page to scroll */
            height: calc(100% + 40px);
            margin: 0;
        }
        div.header {
            width: 100%;
            height: 40px;
            background-color: green;
            overflow: hidden;
        }
        div.content {
            height: 100%;
            height: calc(100% - 40px);
            width: 100%;
            background-color: purple;
            overflow: hidden;
        }
        div.cover {
            position: absolute;
            top: 0;
            left: 0;
            z-index: 100;
            width: 100%;
            height: 100%;
            overflow: hidden;
            background-color: rgba(0, 0, 0, 0.5);
            color: #fff;
            display: none;
        }
        @media screen and (width: 320px) {
            html {
                height: calc(100% + 72px);
            }
            div.cover {
                display: block;
            }
        }
    </style>
    <script>
        var timeout;

        function interceptTouchMove(){
            // and disable the touchmove features 
            window.addEventListener("touchmove", (event)=>{
                if (!event.target.classList.contains('scrollable')) {
                    // no more scrolling
                    event.preventDefault();
                }
            }, false); 
        }

        function scrollDetect(event){
            // wait for the result to settle
            if( timeout ) clearTimeout(timeout);

            timeout = setTimeout(function() {
                console.log( 'scrolled up detected..' );
                if (window.scrollY > 35) {
                    console.log( ' .. moved up enough to go into minimal UI mode. cover off and locking touchmove!');
                    // hide the fixed scroll-cover
                    var cover = document.querySelector('div.cover');
                    cover.style.display = 'none';

                    // push back down to designated start-point. (as it sometimes overscrolls (this is jQuery implementation I used))
                    window.scrollY = 40;

                    // and disable the touchmove features 
                    interceptTouchMove();

                    // turn off scroll checker
                    window.removeEventListener('scroll', scrollDetect );                
                }
            }, 200);            
        }

        // listen to scroll to know when in minimal-ui mode.
        window.addEventListener('scroll', scrollDetect, false );
    </script>
</head>
<body>

    <div class="header">
        <p>header zone</p>
    </div>
    <div class="content">
        <p>content</p>
    </div>
    <div class="cover">
        <p>scroll to soft fullscreen</p>
    </div>

</body>

Полный пример ссылки здесь: https://repos.codehot.tech/misc/ios-webapp-example2.html

Ответ 8

Я наткнулся на это решение от @doublesharp, и он отлично работал у меня, поэтому я подумал, что поделился бы этим здесь:

// track width, set to window width
var width = $(window).width(); 

// fire on window resize
$(window).resize(function() {
    // do nothing if the width is the same
    if ($(window).width()==width) return; 
    // ... your code
});

Итак, для чего-то вроде адресной строки iOS 8 при прокрутке вниз, изменение адресной строки не приведет к потере кода $(window).resize().

Ответ 9

Можно запустить веб-приложение в полноэкранном режиме как на iOS, так и на Android, оно называется PWA, и после долгой работы это был единственный способ обойти эту проблему.

PWA открывают ряд интересных вариантов развития, которые нельзя упускать. Я уже сделал пару, ознакомьтесь с этим Руководством для дизайнеров по государственным и частным тендерам (на испанском языке). А вот английское объяснение с сайта CosmicJS

Ответ 10

Я не делал веб-дизайн для iOS, но из-за того, что, как я помню, видел на сессиях WWDC и в документации, панель поиска в Mobile Safari и панели навигации по ОС теперь будет автоматически изменять размер и уменьшать, чтобы показать больше ваш контент.

Вы можете проверить это в Safari на iPhone и заметить, что при прокрутке вниз, чтобы увидеть больше содержимого на странице, панель навигации/поиска скрыта автоматически.

Возможно, оставив адресную строку/панель навигации как есть, а не создавая полноэкранный режим, это то, что лучше всего. Я не вижу, чтобы Apple делала это в ближайшее время. И в лучшем случае они не контролируют автоматически, когда адресная строка показывает/скрывает.

Конечно, вы теряете экранную недвижимость, особенно на iPhone 4 или 4S, но, похоже, нет альтернативы Beta 4.