Класс L.Control представляет базовый механизм расширения
интерфейса карты. Он используется для создания элементов управления,
которые размещаются поверх карты и взаимодействуют с пользователем
независимо от слоёв данных. В архитектуре Leaflet контролы отделены от
географических объектов и служат исключительно для UI-логики: кнопок,
панелей, переключателей слоёв, шкал масштаба и пользовательских
виджетов.
L.Control — абстрактный класс. Он не используется
напрямую, а служит основой для наследования. Любой контроль в Leaflet
реализует жизненный цикл:
onAdd)onRemove)addTo)Контрол всегда привязан к экземпляру карты и существует в пределах её контейнера.
Каждый контроль принимает набор стандартных параметров:
position — позиция на карте Возможные значения:
toplefttoprightbottomleftbottomrightprefix — CSS-префикс (чаще используется внутри встроенных контролов)
Пример базовой конфигурации:
L.control({ position: 'topright' });
onAdd вызывается при добавлении контроля на карту. Он
должен вернуть DOM-элемент, который будет вставлен в интерфейс.
L.Control.MyControl = L.Control.extend({
onAdd: function(map) {
const container = L.DomUtil.create('div', 'my-control');
container.innerHTML = 'Контроль';
return container;
}
});
Ключевые особенности:
L.DomUtilВызывается при удалении контроля с карты. Используется для очистки событий и освобождения ресурсов.
onRemove: function(map) {
// очистка обработчиков
}
Важно учитывать, что Leaflet не всегда автоматически уничтожает вложенные обработчики, если они были добавлены вручную.
Любой контроль добавляется через метод addTo:
const control = L.control({ position: 'topright' });
control.addTo(map);
или через сокращённую запись:
L.control({ position: 'topright' }).addTo(map);
Для расширения L.Control используется
L.Control.extend.
L.Control.SimpleButton = L.Control.extend({
options: {
position: 'topright'
},
onAdd: function(map) {
const container = L.DomUtil.create('div', 'leaflet-bar leaflet-control');
const button = L.DomUtil.create('a', '', container);
button.innerHTML = '⤢';
button.href = '#';
L.DomEvent.on(button, 'click', function(e) {
L.DomEvent.preventDefault(e);
console.log('Кнопка нажата');
});
return container;
}
});
После определения класса создаётся фабричная функция:
L.control.simpleButton = function(opts) {
return new L.Control.SimpleButton(opts);
};
Использование:
L.control.simpleButton({ position: 'bottomleft' }).addTo(map);
Leaflet предоставляет утилиты:
L.DomUtil.create(tagName, className, container?)L.DomEvent.on(element, event, handler)L.DomEvent.disableClickPropagation(element)L.DomEvent.disableScrollPropagation(element)onAdd: function(map) {
const container = L.DomUtil.create('div', 'control-box');
L.DomEvent.disableScrollPropagation(container);
L.DomEvent.disableClickPropagation(container);
return container;
}
Это предотвращает случайное перемещение карты при взаимодействии с контролом.
L.control.zoom({
position: 'topright'
}).addTo(map);
Функции:
Позволяет переключать базовые и оверлейные слои.
const baseMaps = {
"OSM": osmLayer,
"Satellite": satelliteLayer
};
const overlays = {
"Markers": markersLayer
};
L.control.layers(baseMaps, overlays).addTo(map);
Особенности:
Отображает текст авторства картографических данных.
map.attributionControl.addAttribution('Custom data © company');
или отключение:
L.control.attribution({ position: 'bottomright' }).addTo(map);
Контролы размещаются в одном из четырёх углов карты. Leaflet автоматически группирует их в контейнеры:
.leaflet-top.leaflet-bottom.leaflet-left.leaflet-rightВнутри этих областей контролы выстраиваются вертикально.
Контролы используют стандартные CSS-классы Leaflet:
leaflet-controlleaflet-barleaflet-control-zoomПример кастомного стиля:
.my-control {
background: white;
padding: 8px;
border-radius: 4px;
box-shadow: 0 1px 5px rgba(0,0,0,0.3);
}
Ключевой принцип: визуальная логика полностью отделена от JS.
Контролы часто содержат интерактивные элементы. Основные события:
Пример:
L.DomEvent.on(button, 'click', function(e) {
L.DomEvent.stopPropagation(e);
alert('Действие выполнено');
});
Контрол может хранить состояние:
L.Control.Toggle = L.Control.extend({
onAdd: function(map) {
this._active = false;
const container = L.DomUtil.create('div', 'toggle-control');
const button = L.DomUtil.create('button', '', container);
button.innerHTML = 'OFF';
button.oncl ick = () => {
this._active = !this._active;
button.innerHTML = this._active ? 'ON' : 'OFF';
};
return container;
}
});
Состояние обычно хранится в свойствах объекта контроля.
Контрол получает доступ к карте через аргумент
onAdd(map) и может:
move, zoom,
click)Пример подписки:
onAdd: function(map) {
this._map = map;
map.on('zoomend', this._update, this);
return L.DomUtil.create('div', 'info');
}
Корректное удаление важно для предотвращения утечек:
onRemove: function(map) {
map.off('zoomend', this._update, this);
}
Если контроль содержит таймеры или сторонние обработчики, они также должны быть очищены здесь.
Контроль может включать:
L.Control.DataLoader = L.Control.extend({
onAdd: function(map) {
const container = L.DomUtil.create('div');
fetch('/api/data')
.then(r => r.json())
.then(data => {
container.innerHTML = data.length + ' объектов';
});
return container;
}
});
map.on('moveend', function() {
console.log('Карта перемещена');
});
Контроль может использовать эти события для обновления интерфейса в реальном времени.
L.Control выполняет роль слоя интерфейса поверх
геопространственной модели. Он:
Контролы формируют каркас пользовательского взаимодействия, не вмешиваясь в геоданные и рендеринг слоёв.