В интерфейсах, построенных на HERE Maps API for JavaScript, управление фокусом определяет, как карта и её элементы реагируют на клавиатурную навигацию, переходы между элементами страницы и взаимодействие с доступными компонентами UI. Корректная настройка фокуса критична для доступности, предсказуемого поведения интерфейса и интеграции карты в сложные веб-приложения.
Карта по умолчанию представляет собой интерактивный контейнер, который может перехватывать события клавиатуры, но не всегда участвует в стандартной табуляции документа. Поведение фокуса зависит от конфигурации контейнера, UI-компонентов и подключённых обработчиков событий.
HTML-элемент, в который монтируется карта, не обязан участвовать в
последовательности табуляции. Для управления этим поведением
используется атрибут tabindex.
<div id="map" tabindex="0"></div>
Значение tabindex="0" добавляет контейнер карты в
естественный порядок табуляции документа. При этом карта становится
фокусируемой и может принимать клавиатурные события.
Альтернативный вариант:
<div id="map" tabindex="-1"></div>
Такой контейнер исключается из табуляции, но может быть активирован программно:
document.getElementById('map').focus();
Подход с tabindex="-1" часто используется при
необходимости управлять фокусом через UI-кнопки или сценарии
навигации.
Для корректной интерпретации карты вспомогательными технологиями используется назначение роли и описательных атрибутов:
<div id="map"
role="application"
aria-label="Интерактивная карта">
</div>
Роль application указывает, что внутри контейнера
действует собственная модель обработки клавиатуры, отличная от
стандартной веб-страницы. Это означает, что клавиши могут
интерпретироваться как команды управления картой, а не как навигация по
DOM.
Альтернативный подход — использование role="region" для
более мягкой интеграции в страницу, когда карта не должна полностью
перехватывать управление клавиатурой.
HERE Maps API позволяет обрабатывать события клавиатуры через стандартные DOM-обработчики:
const mapElement = document.getElementById('map');
mapElement.addEventListener('keydown', (event) => {
switch (event.key) {
case 'ArrowUp':
map.setCenter(map.getCenter().translate(0, 0.001));
break;
case 'ArrowDown':
map.setCenter(map.getCenter().translate(0, -0.001));
break;
case '+':
map.setZoom(map.getZoom() + 1);
break;
case '-':
map.setZoom(map.getZoom() - 1);
break;
}
});
Внутренние механизмы карты также могут обрабатывать клавиши навигации, поэтому важно учитывать возможные конфликты между пользовательской логикой и встроенными обработчиками.
UI-слой HERE Maps (H.ui.UI) добавляет интерактивные
элементы: кнопки масштабирования, переключатели слоёв, панели
управления. Эти элементы участвуют в табуляции автоматически.
Последовательность перехода фокуса обычно включает:
Контейнеры UI используют стандартные HTML-кнопки, что обеспечивает встроенную поддержку клавиатуры без дополнительной логики.
При сложных интерфейсах может возникать необходимость контролировать порядок перехода между элементами карты и внешними компонентами страницы. Для этого используется:
tabindexfocus()Пример ограничения перехода:
mapElement.addEventListener('keydown', (event) => {
if (event.key === 'Tab') {
event.preventDefault();
// кастомная логика переключения фокуса
}
});
Такой подход применяется в случаях, когда карта встроена в сложный интерфейс с собственным управлением фокусом.
При использовании role="application" клавиши стрелок и
другие управляющие клавиши перестают выполнять стандартную прокрутку
страницы. Вместо этого они могут быть интерпретированы как команды
управления картой.
Типичное поведение:
При этом важно учитывать необходимость возврата фокуса в документ, чтобы избежать «залипания» клавиатурного управления внутри карты.
Маркерные объекты (H.map.Marker) сами по себе не
являются DOM-элементами, но могут быть связаны с интерактивными
событиями.
Для обеспечения доступности и фокусируемости используется:
tap и clickПример:
marker.addEventListener('tap', () => {
infoBubble.setPosition(marker.getGeometry());
infoBubble.open();
});
При необходимости можно эмулировать фокус на объекте:
mapElement.focus();
selectedMarker = marker;
Информационные окна (H.ui.InfoBubble) часто требуют
отдельного контроля фокуса, особенно при открытии поверх карты.
Типичный сценарий:
infoBubble.addEventListener('open', () => {
infoBubble.getContentElement().focus();
});
При закрытии окна фокус возвращается к маркеру или карте:
infoBubble.addEventListener('close', () => {
mapElement.focus();
});
Одной из типичных проблем является потеря фокуса после взаимодействия с UI-элементами карты. Это проявляется в том, что Tab-навиация выходит за пределы логической структуры интерфейса.
Причины:
tabindexРешение заключается в явном контроле входа и выхода фокуса из компонентов карты.
При отображении модальных панелей поверх карты требуется ограничить навигацию внутри активного слоя:
function trapFocus(container) {
const focusable = container.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
);
focusable[0].focus();
container.addEventListener('keydown', (e) => {
if (e.key === 'Tab') {
const first = focusable[0];
const last = focusable[focusable.length - 1];
if (e.shiftKey && document.activeElement === first) {
e.preventDefault();
last.focus();
} else if (!e.shiftKey && document.activeElement === last) {
e.preventDefault();
first.focus();
}
}
});
}
Такой механизм предотвращает уход фокуса на карту или другие элементы страницы.
Клавиатурное управление масштабом тесно связано с состоянием фокуса
карты. При потере фокуса обработка клавиш + и
- прекращается.
Типичное поведение:
Это требует явного управления фокусом при переключении режимов интерфейса.
При активной карте часто возникает конфликт между прокруткой страницы и перемещением карты. Решение заключается в подавлении стандартного поведения колесика мыши и клавиш прокрутки при фокусе карты.
mapElement.addEventListener('wheel', (event) => {
event.preventDefault();
map.setZoom(map.getZoom() + (event.deltaY < 0 ? 1 : -1));
});
При этом важно не блокировать скролл страницы вне активного состояния карты, чтобы не нарушать общую навигацию интерфейса.
При добавлении слоёв (H.map.layer.TileLayer,
пользовательские overlays) порядок фокуса не меняется автоматически,
поскольку эти элементы не входят в DOM.
Однако связанные UI-компоненты могут динамически появляться и исчезать, что требует:
tabindexПри переключении режимов (например, 2D/3D, ночная тема, изменение слоёв) рекомендуется сохранять контекст фокуса:
const active = document.activeElement;
map.setBaseLayer(newLayer);
setTimeout(() => {
active.focus();
}, 0);
Такой подход предотвращает неожиданный сброс пользовательского контекста взаимодействия.