Особенности разработки интерфейса веб-приложения на iPad

Документ содержит описание возможных проблем, возникающих в процессе адаптации web-приложений для их использования на iPad, и способов их решения.

Следует отметить использование в документе термина "тап" (англ. "tap" — "нажмите") в качестве определения касания пальцем экрана устройства.

Проблемы с установкой фокуса

Ситуация: Если метод .focus() ( document.getElementById('input').focus() ) вызван в обработчике асинхронного события (например, XMLHttpRequest или setTimeout,...), фокусировка будет отложена до следующего тапа. Тап инициирует появление клавиатуры в месте нахождения фокуса. Если тап приводит к уходу фокуса из поля ввода, то клавиатура скроется сразу после появления.

Решение:

  • Обеспечить загрузку ресурса заранее для синхронного открытия формы, если нужно установить фокус;
  • В платформенных контролах для работы с фокусом используются:

    • метод setActive() — позволяет установить или убрать фокус,
    • опция focusOnActivatedOnMobiles — определяет возможность установки фокуса.

    По умолчанию значение опции focusOnActivatedOnMobiles установлено в false, следовательно, фокус не может быть установлен и диалог с клавиатурой не будет инициирован. При необходимости пользователь меняет значение опции на true. В этом случае фокус контролу может быть установлен использованием метода setActive().

Проблемы при работе со стилями

При работе со стилями, с использованием Flexbox, нужно обратить внимание на следующие моменты:

  • для кроссбраузерной разработки необходимо использовать платформенные less-миксины, взять которые можно здесь;
  • в случае особенностей или ошибок отображения приложения на iPad, платформоспецифичным селекторам нужно добавлять .ws-is-mobile-safari, который определен на <body>:
    .ws-is-mobile-safari .my-selector {
     ...
    }
  • при возникающих проблемах в Chrome для iPad рекомендовано использовать .ws-is-mobile-chrome-ios

Для описания ошибок уточним некоторые обозначения:

  • flex — блок, для которого установлено свойство display: display: flex | inline-flex;
  • fix — блок с фиксированной высотой
  • fill — блок с высотой/шириной 100%

Ситуация: если внутри flex-блока расположены блоки fix и fill, возможна ситуация, когда при больших размерах блока fill размер блока fix будет значительно меньше требуемого.

Решение: проблема решается установкой для блока fix свойства flex-shrink: flex-shrink: 0;


Ситуация: flex-fill-блок не занимает все свободное место в родительском блоке.

Решение: проверить родительский блок — он также должен быть flex.

Проблемы, возникающие с событием click

Ситуация: Необходимо учитывать, что тап на DOM-элемент вызывает события с промежутком в 300-350мс между touchend и click, в следующем порядке:


Ситуация: Несколько быстрых тапов подряд активируют зуммирование. При быстром вводе цифр, например — пин-кода "1111" событие клика не сработает четыре раза.

Решение: использование специального компонента SBIS3.BASEAUTH.PinCodeNumber


Ситуация: При установке стиля -webkit-overflow-scrolling: touch; на одном из DOM-элементов возможна ситуация, при которой тап по дочернему элементу не вызывает событие click.

К возникновению ошибки приводят использование DOM — элементов и подписка на событие клика стандартными средствами браузера.

Решение: необходимо использовать платформенные контролы, в которых реализован внутренний механизм _checkClickByTap, эмулирующий клик по элементу, если не сработало событие.

Работа с экранной клавиатурой

Ситуация: Как определить, открыта или нет экранная клавиатура.

Решение: использование событий глобального канала MobileInputFocus и MobileInputFocusOut — на открытие и закрытие клавиатуры соответственно.

Пример:

if (this._options.isCarryOffline) {
   cEventBus.globalChannel().subscribe('MobileInputFocus', this.showClava.bind(this));
   ...
}

Проблемы, возникающие при организации блоков с инерционной прокруткой

Для реализации блоков с инерционной прокруткой рекомендуется использовать платформенный контрол SBIS3.CONTROLS/ScrollContainer, а также отказаться от применения двух вложенных контейнеров с инерционной прокруткой, что позволяет избежать ряда проблем:

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

Проблемы с полями ввода

Использование платформенных контролов для реализации ввода данных пользователя позволит избежать следующих проблем:

  • не скрывается курсор при переходе в режим ReadOnly — проблема решается использованием SBIS3.CONTROLS/TextBox;
  • курсор "уходит" под клавиатуру при подскролле текста — проблема решена программным подскроливанием к области ввода, решение реализовано в компоненте SBIS3.CONTROLS/RichEditor/Components/RichTextArea.

Ошибка браузера Safari на iOS

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

Открыть online.sbis.ru на iOS в единственной вкладке. Затем открыть вторую вкладку и сразу же ее закрыть. В самом низу страницы будет белая полоса. Проблема в том, что браузер не обновляет высоту документа при описанном выше сценарии.

До версии iOS 10.3 было возможно отследить состояние, когда ошибка повторялась, проверяя на равенство высоты на window и document, и с помощью стилей компенсировать неправильно рассчитанную высоту. После выхода iOS 10.3 отследить это состояние невозможно.

Подробности работы с ошибкой можно посмотреть здесь.