- PVSM.RU - https://www.pvsm.ru -
Наверное, все при взгляде на этот экран мысленно переносят обе руки на клавиатуру. Да, тут можно было навигироваться без мышки и это было быстро и хорошо! Многие до сих пор используют подобные менеджеры (Total commander, Far etc).
С другой стороны, почти на всех современных сайтах, порталах и решениях, построенных для веба, пользователь вынужден постоянно отрывать руки от клавиатуры, целиться мышкой в кнопку/иконку/поле, а затем опять возвращать руки на клавиатуру для ввода текста.
Как же достичь удобства навигации без мышки в вебе?
Большая часть продуктов, которые разрабатывает и внедряет наша компания, выходит на конечного пользователя. Операторы колл-центров, инженеры, менеджеры – все они работают с пользовательским интерфейсом «для внутреннего использования» – B2B интерфейсами. Возможность работы с системой с клавиатуры без использования мыши – важное требование в B2B интерфейсах. Почему?
Такая навигация может выглядеть не «секси» и требовать больше времени на обучение, но бонусы от использования значительно превышают эти минусы.
Есть большое количество web-based пользовательских интерфейсов. Необходимо:
Существует четыре основных подхода к навигации клавиатурой, рассмотрим их:
Табуляция — переход между элементами интерфейса с помощью клавиши tab (shift+tab).
Горячие клавиши (в просторечии хоткеи) — сочетание клавиш, которое вызывает определённую функцию. Это позволяет упростить доступ к основным функциям системы. Всё больше сайтов начинают использовать хоткеи на свои страницах для доступа к самым востребованным функциям, среди них: Habrahabr, яндекс, гугл почта и другие. Но что делать, если функций много, и на каждой странице разные? Просто невозможно будет запомнить все хоткеи, а значит, использование не будет эффективным. Так же есть проблема контекста: когда на странице несколько таблиц и несколько кнопок save, например.
Пример реализации: расширения для Firefox используют подход с hotkeys, очень распространены в десктоп приложениях (пример — аутлук).
Когда элементы на веб страницах стали позиционировать с помощью css, навигация табом перестала справляться со своей задачей: курсор перескакивал по элементам дизайна в порядке их объявления в html документе, а не в том, в каком их видит пользователь. Тогда некоторые браузеры (Firefox, Opera) реализовали пространственную навигацию. Они позволяли пользователям использовать сочетания shift+стрелки для перемещения между элементами дизайна, причём следующий элемент определялся исходя из его фактического расположения на экране.
Особенность этого подхода в том, что курсор пользователя перемещается не только по элементам форм и ссылкам, а по всему содержимому страницы (как в ворде). Перемещаться можно, как и в пространственном подходе, в четырёх направлениях.
Вышеприведенные решения as is нам не подходят из-за отсутствия поддержки во всех браузерах, в них отсутствует возможность тонкой настройки для конкретных страниц, а также хотелось бы, чтобы и хоткеи и пространственная навигация настраивались единообразно в одном месте.
Ключевыми особенностями Mouseless являются:
Страница делится на блоки с помощью привычных CSS селекторов. Блоки могут иметь дочерние блоки. Внутри каждого блока определяется свой набор хоткеев (JSON объект). Хоткеи могут наследоваться внутренними блоками, т.е. у хоткеев появляется область видимости, которым можно управлять (например, хоткей для сохранения один и тот же в разных блоках, но работает по-разному в зависимости от текущего блока).
На рисунке показано разделение на блоки и подблоки.
Конфигурация каждого блока представляет из себя json объект, json объекты для всех блоков образуют конфигурацию страницы.
Пространственная навигация в данном случае является частным случаем хоткеев. Сводим к минимуму кол-во обязательных параметров конфигурации, базовая поддержка должна быть доступна с минимумом действий. Простейшая конфигурация:
new MouselessBlock({ //объявление блока
selector: "#blockId", // селектор задаёт границы блока
childSelector: “a”, // селектор определяет элементы на которые будет перемещаться фокус
keys: [ // массив хранит все хоткеи, используемые в данном блоке
new MouselessAction({key: ncKey.KEY_LEFT, action: ncKey.gotoPrevElem }), //по нажатию на клавишу влево выполнить переход на предыдущий элемент
new MouselessAction({key: ncKey.KEY_RIGHT, action: ncKey.gotoNextElem })
]
});
Внутри блока #blockId можно перемещать фокус между ссылками клавишами влево и вправо. gotoPrevElem/gotoNextElem служебные функции, можно так же использовать свои кастомные функции.
На реальных кейсах расширяем базовую библиотеку:
ncKey.addBaseConf(parentSelector, blocks); //добавление блоков в основную конфигурацию
ncKey.addCustomConf(parentSelector, blocks); //добавление блоков в конфигурацию динамически подключаемых модальных блоков
//parentSelector - селектор родительского блока, если "" - добавление в корень конфигурации.
//blocks - массив блоков для добавления
var curFocus = ncKey.saveFocus();
…
ncKey.restoreFocus(curFocus);
ncKey.addCustomConf("", [new MouselessBlock({//блок, описывающий попап
selector:"#popup-window",
childSelector: ncKey.FOCUSABLE_SELECTOR,
keys: [new MouselessAction({key: ncKey.KEY_ESCAPE, action: closePopup}),
new MouselessAction({key: ncKey.KEY_S, action: saveAndClosePopup})
],
childBlocks: [new MouselessBlock({ //дочерний блок с контентом
selector:"#popup-window .body",
childSelector: ncKey.FOCUSABLE_SELECTOR,
ring: false,
keys: [...]
}),
new MouselessBlock({ //дочерний блок с кнопками
selector:"#popup-window .btns",
childSelector: ncKey.FOCUSABLE_SELECTOR,
ring: false,
keys: [...]
})
]
})
]);
Закрытие попапа с сохранением и без будет работать во всех блоках.
Конфигурация блока на примере NavigationTree (раскрывающее дерево):
new MouselessBlock({
selector: "#navigationTree",
childSelector: "li > a:visible",
ring: true,
keys: [ new MouselessAction({key: ncKey.KEY_LEFT, action: ncKey.gotoPrevBlock, ctrl: true}),
new MouselessAction({key: ncKey.KEY_RIGHT, action: ncKey.gotoNextBlock, ctrl: true}),
new MouselessAction({key: ncKey.KEY_UP, action: ncKey.gotoPrevElem, ctrl: false}),
new MouselessAction({key: ncKey.KEY_DOWN, action: ncKey.gotoNextElem, ctrl: false}),
new MouselessAction({key: ncKey.KEY_RIGHT, action: openNavTreeNode, ctrl: false}),
new MouselessAction({key: ncKey.KEY_LEFT, action: closeNavTreeNode, ctrl: false})
]});
Теперь можно ходить по дереву стрелками вверх-вниз, открывать-закрывать ветки влево-вправо. Функции openNavTreeNode/closeNavTreeNode были написаны до внедрения Mouseless (были опубликованы как api к дереву).
Таким образом, даже в этом случае не пришлось писать новый код, обходимся простой конфигурацией.
CSS легко заменяется под любую тему, достаточно описать правила для подсветки активируемых элементов и активного. Можно добавить свои, более сложные, для конкретных блоков или элементов.
Внедрив Mouseless в наши решения мы получили библиотеку, которая позволяет обеспечить быструю базовую поддержку навигации с клавиатуры, с одной стороны, и глубокую настройку для достижения максимальной эффективности и удобства использования, с другой.
Дополнительным бонусом стало то, что мы покрыли часть рекомендаций W3C “Web Content Accessibility Guidelines” ( www.w3.org/TR/WCAG20 [1] ).
Работа в этом направлении не закончена, будем продолжать, ждём реакцию сообщества.
Автор: NetСracker
Источник [2]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/ux/106208
Ссылки в тексте:
[1] www.w3.org/TR/WCAG20: http://www.w3.org/TR/WCAG20/
[2] Источник: http://habrahabr.ru/post/273071/
Нажмите здесь для печати.