Клавиатурные события позволяют управлять картой без использования мыши или сенсорного экрана. Они применяются для навигации по карте, масштабирования, перемещения фокуса между элементами интерфейса и создания специализированных механизмов управления геоданными.
Поддержка клавиатуры является важной частью доступности веб-приложений. Leaflet содержит встроенную систему обработки нажатий клавиш, благодаря которой пользователь может взаимодействовать с картой через стандартные элементы управления.
По умолчанию клавиатурное управление активировано.
const map = L.map('map', {
keyboard: true
});
Параметр keyboard определяет, будет ли карта реагировать
на нажатия клавиш.
Если необходимо полностью отключить такую возможность:
const map = L.map('map', {
keyboard: false
});
Или после создания карты:
map.keyboard.disable();
Повторное включение:
map.keyboard.enable();
После получения фокуса карта начинает реагировать на ряд клавиш.
Стрелки клавиатуры перемещают карту:
| Клавиша | Действие |
|---|---|
| ← | Сдвиг влево |
| → | Сдвиг вправо |
| ↑ | Сдвиг вверх |
| ↓ | Сдвиг вниз |
Пример:
↑
Карта смещается к северу.
↓
Карта смещается к югу.
Для изменения масштаба используются клавиши:
+
-
или
=
-
В зависимости от раскладки клавиатуры и браузера.
Карта начинает обрабатывать клавиатурные события только после получения фокуса.
Leaflet автоматически назначает контейнеру карты атрибут
tabindex.
Пример HTML:
<div id="map"></div>
После щелчка мышью по карте либо перехода через клавишу Tab карта становится активной.
Проверить элемент контейнера:
const container = map.getContainer();
console.log(container.tabIndex);
Для работы со стандартными клавиатурными событиями браузера часто требуется ссылка на контейнер карты.
const mapContainer = map.getContainer();
После этого можно использовать обычные обработчики JavaScript.
mapContainer.addEventListener('keydown', function(event) {
console.log(event.key);
});
Событие keydown возникает в момент нажатия клавиши.
Пример регистрации:
map.getContainer().addEventListener(
'keydown',
function(event) {
console.log('Нажата клавиша:', event.key);
}
);
При нажатии стрелки вверх:
Нажата клавиша: ArrowUp
Событие keyup вызывается после отпускания клавиши.
map.getContainer().addEventListener(
'keyup',
function(event) {
console.log('Отпущена:', event.key);
}
);
Применяется для завершения операций перемещения, рисования или навигации.
Современный способ проверки основан на свойстве key.
map.getContainer().addEventListener(
'keydown',
function(event) {
if (event.key === 'Enter') {
console.log('Enter');
}
}
);
Другие популярные значения:
event.key === 'Escape'
event.key === 'ArrowLeft'
event.key === 'ArrowRight'
event.key === 'ArrowUp'
event.key === 'ArrowDown'
event.key === ' '
event.key === '+'
event.key === '-'
Свойство code описывает физическую клавишу независимо от
раскладки.
map.getContainer().addEventListener(
'keydown',
function(event) {
console.log(event.code);
}
);
Примеры:
KeyA
KeyW
KeyD
KeyS
ArrowLeft
ArrowRight
Это особенно полезно для игровых сценариев управления картой.
Часто вместо стрелок используются игровые клавиши.
const step = 100;
map.getContainer().addEventListener(
'keydown',
function(event) {
if (event.code === 'KeyW') {
map.panBy([0, -step]);
}
if (event.code === 'KeyS') {
map.panBy([0, step]);
}
if (event.code === 'KeyA') {
map.panBy([-step, 0]);
}
if (event.code === 'KeyD') {
map.panBy([step, 0]);
}
}
);
Метод panBy() перемещает карту на указанное количество
пикселей.
Масштабирование можно реализовать самостоятельно.
map.getContainer().addEventListener(
'keydown',
function(event) {
if (event.key === '+') {
map.zoomIn();
}
if (event.key === '-') {
map.zoomOut();
}
}
);
Используемые методы:
map.zoomIn();
map.zoomOut();
Метод setZoom() позволяет задавать точный уровень.
map.getContainer().addEventListener(
'keydown',
function(event) {
if (event.key === '1') {
map.setZoom(5);
}
if (event.key === '2') {
map.setZoom(10);
}
if (event.key === '3') {
map.setZoom(15);
}
}
);
Клавиатурные команды могут быстро перемещать карту к заранее известным координатам.
map.getContainer().addEventListener(
'keydown',
function(event) {
if (event.key === 'h') {
map.setView([51.505, -0.09], 13);
}
}
);
После нажатия клавиши карта перемещается к заданной точке.
Часто требуется показывать различные слои по горячим клавишам.
map.getContainer().addEventListener(
'keydown',
function(event) {
if (event.key === '1') {
map.addLayer(citiesLayer);
map.removeLayer(roadsLayer);
}
if (event.key === '2') {
map.addLayer(roadsLayer);
map.removeLayer(citiesLayer);
}
}
);
Такой подход удобен для GIS-приложений.
map.getContainer().addEventListener(
'keydown',
function(event) {
if (event.key === 'Enter') {
const center = map.getCenter();
L.marker(center).addTo(map);
}
}
);
Маркер создаётся в центре текущего вида карты.
let selectedMarker;
map.getContainer().addEventListener(
'keydown',
function(event) {
if (
event.key === 'Delete' &&
selectedMarker
) {
map.removeLayer(selectedMarker);
selectedMarker = null;
}
}
);
Подобная схема часто применяется в редакторах карт.
map.getContainer().addEventListener(
'keydown',
function(event) {
if (event.key === 'Escape') {
drawingMode = false;
console.log('Режим рисования отключён');
}
}
);
Клавиша Escape традиционно используется для отмены текущей операции.
map.getContainer().addEventListener(
'keydown',
function(event) {
if (
event.ctrlKey &&
event.key === 's'
) {
event.preventDefault();
saveProject();
}
}
);
Свойство ctrlKey показывает состояние клавиши Ctrl.
map.getContainer().addEventListener(
'keydown',
function(event) {
if (
event.shiftKey &&
event.key === 'ArrowRight'
) {
map.panBy([300, 0]);
}
}
);
Такой механизм позволяет реализовать ускоренное перемещение карты.
if (
event.altKey &&
event.key === 'm'
) {
console.log('Специальный режим');
}
Некоторые клавиши имеют встроенные действия браузера.
Например:
event.preventDefault();
Пример:
map.getContainer().addEventListener(
'keydown',
function(event) {
if (event.key === ' ') {
event.preventDefault();
console.log('Пробел обработан');
}
}
);
Без этого страница может прокручиваться вниз.
Для предотвращения передачи события другим элементам используется:
event.stopPropagation();
Пример:
map.getContainer().addEventListener(
'keydown',
function(event) {
event.stopPropagation();
}
);
При удержании клавиши событие keydown вызывается
многократно.
map.getContainer().addEventListener(
'keydown',
function(event) {
if (event.key === 'ArrowRight') {
map.panBy([20, 0]);
}
}
);
Однако скорость зависит от настроек операционной системы.
Для полного контроля обычно применяется собственный цикл анимации.
Создание объекта состояния:
const keys = {};
Запоминание нажатий:
document.addEventListener(
'keydown',
function(event) {
keys[event.code] = true;
}
);
Фиксация отпускания:
document.addEventListener(
'keyup',
function(event) {
keys[event.code] = false;
}
);
Использование:
if (keys.KeyW) {
map.panBy([0, -5]);
}
Такой подход используется в сложных интерактивных картографических приложениях.
Пример переключения между объектами.
const markers = [
marker1,
marker2,
marker3
];
let currentIndex = 0;
Обработчик:
map.getContainer().addEventListener(
'keydown',
function(event) {
if (event.key === 'Tab') {
event.preventDefault();
currentIndex++;
if (currentIndex >= markers.length) {
currentIndex = 0;
}
map.panTo(
markers[currentIndex].getLatLng()
);
}
}
);
Карта автоматически перемещается к выбранному объекту.
При разработке интерфейсов рекомендуется соблюдать несколько правил:
const container = map.getContainer();
container.addEventListener(
'keydown',
function(event) {
switch(event.key) {
case 'ArrowUp':
map.panBy([0, -100]);
break;
case 'ArrowDown':
map.panBy([0, 100]);
break;
case 'ArrowLeft':
map.panBy([-100, 0]);
break;
case 'ArrowRight':
map.panBy([100, 0]);
break;
case '+':
map.zoomIn();
break;
case '-':
map.zoomOut();
break;
case 'Home':
map.setView(
[51.505, -0.09],
13
);
break;
case 'Enter':
L.marker(
map.getCenter()
).addTo(map);
break;
}
}
);
Данный подход объединяет навигацию, изменение масштаба, создание объектов и возврат к исходному положению карты в рамках единой системы клавиатурного управления.