Frontender Magazine

Использование полноэкранного режима на мобильных устройствах

«Одно из наилучших качеств нативных приложений — это то, что они работают в полноэкранном режиме.» — слышу это постоянно от множества людей.

Это расхожее суждение меня в некоторой степени раздражает. Да, веб-страницы отображаются не в полноэкранном режиме: в браузере есть адресная строка и ещё некоторые элементы навигации. Однако, большинство браузеров довольно быстро убирает всё лишнее с экрана.

Мы можем без затруднений создавать полноэкранные веб-сайты и приложения с эффектом присутствия, однако, что характерно для веб, для этого есть несколько способов. Это особенно важно сейчас, когда большее количество браузеров поддерживает полноэкранный режим, который обеспечивает эффект «установленного веб-приложения».

Пример переключения отображения сайта на полноэкранный режим в Chrome под Android

Переход в полноэкранный режим

Есть несколько способов, с помощью которых пользователь или разработчик может перевести веб-приложение в полноэкранный режим.

Имитация: автоматическое скрытие адресной строки

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

window.scrollTo(0,1);

Хочу дать вам дружеский совет. Такой способ существует и он работает, однако это хак. Пожалуйста, не используйте его.

Это довольно простой способ. Страница загружается и строка браузера получает указание скрыться из виду. К сожалению, он не соответствует стандартам и плохо поддерживается. Вам придётся поработать над решением для обхода некоторых особенностей. Например, браузеры часто восстанавливают расположение страницы когда пользователь на неё возвращается. Использование window.scrollTo блокирует такую возможность, что раздражает пользователей. Чтобы обойти эту проблему придётся сохранять последнее расположение в локальном хранилище (localStorage) и придумать решение для пограничных случаев (например, когда пользователь открывает страницу в нескольких окнах).

Запрос на перевод браузера в полноэкранный режим как реакция на жест пользователя

Не все платформы одинаковы. Для Safari под iOS нет Fullscreen API, в отличии от Chrome, Android и Firefox.

Для большинства приложений вам придётся использовать комбинацию из JS API и CSS-селекторов, предложенных в спецификации полноэкранного режима.

Главные JS API, о которых вам нужно знать при разработке приложения с полноэкранным режимом:

Обратите внимание на то, что в версиях с префиксами регистр буквы «S» в слове «screen» абсолютно непоследователен. Это неудобно, но такова текущая проблема спецификаций, которые у нас есть.

Когда ваше приложение отображается в полноэкранном режиме, элементы управления интерфейсом браузера больше не доступны. Способ взаимодействия пользователя с интерфейсом в результате меняется. Ему не доступны стандартные элементы управления навигацией, такие как кнопки «Вперёд» и «Назад»; у него есть средство «аварийного» выхода из полноэкранного режима — кнопка «Обновить». Необходимо учесть этот сценарий. Стиль и представление сайта при переходе в полноэкранный режим можно изменить с помощью CSS-селекторов.

<button id="goFS">Перейти в полноэкранный режим<button> 
<script>
   var goFS = document.getElementById("goFS");
   goFS.addEventListener("click", function() {
      document.body.requestFullScreen();
   }, false);
</script>

Пример выше довольно далёк от реальности; я упустил все сложности, связанные с использованием вендорных префиксов.

Горите в аду, вендорные префиксы!

На самом деле код будет намного более сложным. Команда Mozilla создала очень полезный скрипт, который можно использовать для запуска полноэкранного режима. Как видите, из-за ситуации с вендорными префиксами, он довольно сложный и громоздкий в сравнении с упомянутым API. Даже в слегка упрощённом виде, приведённом ниже, код остается сложным:

function toggleFullScreen() {
  var doc = window.document;
  var docEl = doc.documentElement;

  var requestFullScreen = docEl.requestFullscreen || docEl.mozRequestFullScreen || docEl.webkitRequestFullScreen;
  var cancelFullScreen = doc.exitFullscreen || doc.mozCancelFullScreen || doc.webkitExitFullscreen;

  if(!doc.fullscreenElement && !doc.mozFullScreenElement && !doc.webkitFullscreenElement) { 
    requestFullScreen.call(docEl);
  }
  else {
    cancelFullScreen.call(doc);  
  }
}

Мы, веб-разработчики, не любим излишества в коде. Можно использовать хороший общий API от Синдре Сорхуса (Sindre Sorhus) — модуль Screenfull.js, который объединяет два немного разных JS API и вендорные префиксы в один последовательный API.

Запуск страницы в полноэкранном режиме

Запуск веб-страницы в полноэкранном режиме при открытии её пользователем невозможен. Разработчикам браузеров прекрасно известно, что переход в полноэкранный режим при каждой загрузке страницы ужасно раздражает, потому для его запуска необходим жест пользователя. Однако у пользователей есть возможность «установить» приложение, его инсталляция является для операционной системы сигналом, что пользователь хочет запускать сайт как приложение.

Это довольно просто реализовать на ведущих мобильных платформах используя мета теги или файл манифеста.

iOS

С самого запуска iPhone, пользователи имеют возможность устанавливать веб-приложения на рабочий стол и запускать их в полноэкранном режиме.

<meta name="apple-mobile-web-app-capable" content="yes">

От Apple:

Если для content задано значение yes, веб-приложение запускается в полноэкранном режиме; в противном случае оно запускается в обычном режиме. По умолчанию для просмотра веб-контента используется Safari. Определить загрузку страницы в полноэкранном режиме можно с помощью неизменяемого булевого свойства JavaScript window.navigator.standalone.

Chrome под Android

Команда Chrome недавно ввела свойство, которое говорит браузеру, что нужно загружать страницу в полноэкранном режиме, если пользователь добавил её на рабочий стол. Это напоминает схему для Safari под iOS:

<meta name="mobile-web-app-capable" content="yes">

От Chrome:

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

Firefox OS

В Firefox OS введена модель устанавливаемых веб-приложений и пакетированных приложений для разработчиков, которые создают приложения для телефона пользователя. Эта модель немного более сложная, однако вписывается в общий подход к устанавливаемым приложениям. Разработчик должен определить манифест для приложения, который Firefox OS обрабатывает в процессе установки.

От Mozilla:

{
  "name": "My App",
  "description": "My elevator pitch goes here",
  "launch_path": "/",
  "icons": {
    "128": "/img/icon-128.png"
  },
  "fullscreen": true
}

Советы по использованию API

Переход документа в полноэкранный режим

Нет ничего странного в намерении вывести элемент body в полноэкранный режим, однако на движке WebKit и Blink можно наблюдать странный эффект уменьшения ширины тела документа до наименьшего размера, при котором на нём помешается весь контент (в Gecko от Mozilla всё нормально).

Рисунок 1

Рисунок 1: Полноэкранный режим для элемента body

Чтобы это исправить, используйте вместо body элемент document:

document.documentElement.requestFullScreen();

Рисунок 2

Рисунок 2: Полноэкранный режим для элемента document.

Отображение элемента video в полноэкранном режиме

Перевести элемент video в полноэкранный режим можно точно так же как и любой другой элемент. Можно применить для элемента video метод requestFullScreen.

<video id=videoElement></video>
<button id="goFS">Перейти в полноэкранный режим</button> 
<script>
   var goFS = document.getElementById("goFS");
   goFS.addEventListener("click", function() {
      var videoElement = document.getElementById("videoElement");
      videoElement.requestFullScreen();
   }, false);
</script>

Если для вашего элемента <video> не указан атрибут controls, пользователь не сможет контролировать воспроизведение видео в полноэкранном режиме. Желательно создать простой контейнер-обёртку для video и элементов управления, которые должен увидеть пользователь.

<div id="container">
  <video><video>
  <div>
    <button>Воспроизвести<button>
    <button>Стоп<button>
    <button id="goFS">Переход в полноэкранный режим<button> 
  <div>
<div>
<script>
   var goFS = document.getElementById("goFS");
   goFS.addEventListener("click", function() {
      var container = document.getElementById("container");
      container.requestFullScreen();
   }, false);
<script>

Так мы получаем больше гибкости, ведь для объекта-контейнера можно использовать псевдо-селектор CSS (например, чтобы спрятать кнопку «goFS»).

<style>
#goFS:full-screen #goFS {
  display: none;
} 
#goFS:-webkit-full-screen #goFS {
  display: none;
} 
#goFS:-moz-full-screen #goFS {
  display: none;
} 
<style>

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

Рекомендации по UX

Не рассчитывайте на элементы управления навигацией

В устройствах с iOS и Firefox OS нет физической кнопки «Назад» и в них не предусмотрен жест обновления, следовательно вам нужно позаботиться чтобы пользователь мог пользоваться навигацией и не застрять в процессе.

На всех ведущих платформах можно легко определить воспроизведение полноэкранного режима или режима установленного приложения.

iOS

if(window.navigator.standalone == true) {
  // Мое приложение установлено и следовательно воспроизводится в полноэкранном режиме
}

Chrome под Android

Когда страница запущена в режиме установленного приложения, Chrome не работает в истинном полноэкранном режиме, потому document.fullscreenElement возвращает null и CSS-селекторы не работают. У Chrome также нет API, похожего на свойство iOS navigator.standalone.

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

selector:-webkit-full-screen {
  display: block; // отображаем элемент только в полноэкранном режиме
}

selector {
  display: none; // прячем элемент когда полноэкранный режим отключён
}

Firefox

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

selector:-moz-full-screen {
  display: block; // отображаем элемент только в полноэкранном режиме
}

selector {
  display: none; // прячем элемент когда полноэкранный режим отключён
}

Спецификация

Формулировка в спецификации немного отличается от реализации в Chrome и Firefox, однако на практике всё выглядит так же.

selector:fullscreen {
  display: block;
}

selector {
  display: none; // прячем элемент когда полноэкранный режим отключён
}

Сохранение отображения в полноэкранном режиме

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

Если вы хотите зафиксировать отображение в полноэкранном режиме, у вас есть два варианта:

  1. использовать механизмы установленного веб-приложения для перехода в полноэкранный режим
  2. Управляйте состоянием интерфейса и приложения используя фрагмент #.

Используя #синтаксис для обновления url (window.location = "#somestate") и установив обработчик для события window.onhashchange можно использовать стек истории браузера для управления изменениями состояния приложения, позволить пользователю использовать кнопку «назад» на устройстве или предложить простую программную кнопку «назад» используя History API:

window.history.go(-1)

Дайте пользователю возможность выбирать когда переходить в полноэкранный режим

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

Не перехватывайте первое событие касания для запуска requestFullScreen.

  1. Это раздражает.
  2. В определённый момент в будущем браузер может выдать пользователю запрос на разрешение перехода в полноэкранный режим.

Рисунок 3

Рисунок 3: FirefoxOS запрашивает разрешение на переход в полноэкранный режим.

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

Не спамьте пользователя предложениями установить приложение на рабочий стол

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

Заключение

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

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

Если вы заметили ошибку, вы всегда можете отредактировать статью, создать issue или просто написать об этом Антону Немцеву в skype ravencry.

Paul Kinlan
Автор:
Paul Kinlan
GitHub:
PaulKinlan
Twitter:
@paul_kinlan
Сaйт:
http://paul.kinlan.me/
Email:
paul.kinlan@gmail.com
Наталья Фадеева
Переводчик:
Наталья Фадеева
вКонтакте:
natatik_l
Twitter:
@very_busy_girl
GitHub:
NatalieF