Поддержка Сенсорного Управления В Javascript



Поддержка сенсорного управления в JavaScript

Какие проблемы могут возникнуть у фронтенд-программиста, если тестировщик запустит свое приложение на iPad с новой клавиатурой с трекпадом, на планшете Windows с неопределенным состоянием «режим планшета» или на ноутбуке с подключенным к нему телевизором с поддержкой Multi-touch? Это не полный список приемлемых конфигураций оборудования, которые мы поддерживаем при разработке системы СБИС.

Сегодня СБИС — это не только привычное решение для отчетности, электронного документооборота и учета, но и набор инструментов для автоматизации розничной торговли, общественного питания, доставки и логистики.

В этих сферах нужно уметь хорошо работать на самых разных планшетах и гаджетах с разными экранами и типами устройств ввода.

И не всегда проблемы могут быть связаны с экзотическим сочетанием настроек операционной системы и драйверов: если вы возьмете обычный iPad с браузером Safari, Android-планшет или ноутбук-трансформер на Windows 10 с последней версией Google Chrome, то у каждого будет свой набор ошибок и особенности обработки пользовательского ввода.

Эта статья о том, как и, самое главное, зачем внедрять режим поддержки сенсорного ввода в обычные веб-приложения.

Основными особенностями сенсорного режима при организации взаимодействия с пользователем являются отсутствие указателя мыши и появление виртуальной клавиатуры.

Соответственно, на уровне приложения необходимо обеспечить:

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



Определение момента активации режима Touch

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

Например, отсоединить экран от ноутбука-трансформера, работать с ним как с планшетом, а затем присоединить его обратно и продолжить работу с мышкой.

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

Другой пример: в наших переговорных комнатах к ноутбукам подключены телевизоры с поддержкой Multi-touch. Формально браузер на ноутбуке думает, что его устройство поддерживает события Touch. Именно на этой аппаратной конфигурации мы обнаружили проблему в нашем первом алгоритме определения режима Touch по наличию поддержки специализированных событий.

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

Сегодня мы определяем режим Touch, анализируя реакцию на события touchstart и mousemove: если вызову mousemove не предшествовал touchstart, то пользователь перемещает мышь, в противном случае он нажимал пальцем.

Исходный код примерно такой

  
   

touchstartHandler() { this._isTouch = null; } mousemoveHandler() { if (this._isTouch === null) { this.updateState(true); } else if (this._isTouch) { this.updateState(false); } } updateState(state) { this._isTouch = state; this._triggerEvent(); }

В результате генерируется событие и мы сохраняем значение режима в объекте с информацией о текущем окружении, а также устанавливаем на тело классы is-touch или is-hover.

:функции поддержки при наведении

В нашем приложении мы полностью отказываемся от поддержки :hover при работе в сенсорном режиме.

Все стили, поддерживающие :hover, выглядят примерно так:

body.is-hover .

my-button:hover { }

Этот метод работает надежнее стандартного @media (hover:hover), который не отключает поддержку свойства hover в Chrome и Firefox при работе пальцами.

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

Особое внимание следует уделить использованию этого псевдокласса для управления видимостью блока.



Поддержка сенсорного управления в JavaScript

Наши компоненты списка, таблицы и дерева используют селекторы :hover для отображения операций со строками при наведении курсора (например, редактирование, удаление и т. д.).

Использование :hover в iOS приведет к тому, что первый щелчок по строке изменит только видимость элементов управления, поэтому пользователю придется сделать второй щелчок.

Но в Android и Windows никто никогда не увидит операций над строкой.

При переключении в сенсорный режим компоненты списка отключают поддержку :hover и включают поддержку управления жестами, например пролистыванием или длительным нажатием.



Поддержка сенсорного управления в JavaScript

Мы обрабатываем жесты смахивания независимо на основе события перемещения мыши в сенсорном режиме при следующих условиях:

  • минимальное расстояние горизонтального перемещения не менее 50 пикселей;
  • максимальное отклонение по вертикали не более 25px;
  • продолжительность жеста не более 600мс;
  • жест не регистрируется в диапазоне 25 пикселей от границы экрана, поскольку браузер воспринимает это событие как изменение навигации.



Особенности при работе с виртуальной клавиатурой

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

Иногда мы сами логируем ошибки: Ссылка 1 Ссылка 2 Иногда мы находим уже зарегистрированные: Ссылка 1 Ссылка 2 В демо-примерах проблема может выглядеть безобидной, но в реальном рабочем приложении всё прыгает в разные стороны и несколько раз.

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

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

В идеале сохраняйте высоту в пределах 300 пикселей, чтобы обеспечить комфортную работу даже на небольших POS-терминалах.



Поддержка сенсорного управления в JavaScript

Самый простой пример: как не размещать поля логина и пароля на форме авторизации

Поддержка сенсорного управления в JavaScript

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

Всплывающие подсказки и обычные диалоги следует по возможности располагать в видимой области экрана.



Поддержка сенсорного управления в JavaScript

На первый взгляд задача не выглядит сложной, но до недавнего времени у нее не было 100% рабочего решения: Во-первых, API браузера не предоставлял информацию о том, отображалась ли виртуальная клавиатура или нет. Нам приходилось отслеживать приход и уход фокуса для каждого поля ввода.

В этом случае клавиатуру можно просто скрыть и на состояние фокуса это никак не повлияет. Во-вторых, никто не знал реального размера клавиатуры.

Коэффициенты мы подобрали в зависимости от ориентации экрана: 0,3 для книжной и 0,55 для альбомной.

Но как только Smart Keyboard подключили к iPad, все рассчитанные коэффициенты оказались бесполезными и даже вредными, т.к.

высота виртуальной клавиатуры сжалась до одной строки.



Поддержка сенсорного управления в JavaScript

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

ВизуальныйВьюпорт .

Прошло целых 12 лет с момента выпуска iOS, прежде чем разработчики смогли получить информацию об изменении размера области просмотра при показе виртуальной клавиатуры.

Новый API позволяет решить сразу 2 задачи:

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

День прекращения поддержки iOS12 станет нашим большим праздником, потому что.

мы наконец сможем переключиться на поддержку VisualViewport, удалив всю магию из кода.



Не злоупотребляйте ручной фокусировкой

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

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

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

Лично я видел проблемы на iPad в разное время как в Гугле при поиске изображений, когда клавиатура для поля поиска скрывалась сразу после отображения и сама открывалась обратно, так и в Яндекс Маркете, когда клавиатура пропадала при вводе текста в поиске поле.

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

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

В этом случае, например, после навигации в SPA-приложении или после открытия диалога вы не сможете установить фокус в поле ввода на iOS. Таким образом, каждый из наших компонентов имеет метод активации для установки фокуса.

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

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



Прикоснуться легко

Таким образом, в современных браузерах с помощью простого набора приемов можно довольно легко организовать поддержку Touch-режима.

Это те самые 20% усилий, которые помогут достичь 80% результата: для большинства пользователей приложение будет предсказуемо работать на их аппаратных конфигурациях.

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

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

Если эта тема интересна, я готов продолжить их описание в следующей статье.

Теги: #Разработка сайтов #JavaScript #Юзабилити #веб-дизайн #сенсорный экран

Вместе с данным постом часто просматривают: