В Leaflet система событий построена вокруг архитектуры подписки на
события, возникающие у карты, слоёв и отдельных объектов. Каждый объект,
наследующий L.Evented, способен регистрировать обработчики,
удалять их и инициировать собственные события.
Основные механизмы работы:
ononceofffireКаждое событие передаёт объект event, содержащий
контекст произошедшего действия.
Основной способ подключения логики к событиям — метод
on.
map.on('click', function (e) {
console.log('Клик по карте');
});
При каждом срабатывании события в обработчик передаётся объект события:
map.on('click', function (e) {
console.log(e.type); // click
console.log(e.latlng); // координаты клика
console.log(e.containerPoint); // пиксельные координаты
});
Типичный объект события включает:
type — имя событияtarget — объект, вызвавший событиеlatlng — географические координаты (для карты и
маркеров)layerPoint / containerPoint — координаты в
пикселяхoriginalEvent — исходное DOM-событиеКонтроль срабатывания событий обычно осуществляется через логирование и трассировку вызовов.
function logEvent(e) {
console.log('Event:', e.type, e);
}
map.on('click', logEvent);
map.on('zoomstart', logEvent);
map.on('zoomend', logEvent);
map.on('move', logEvent);
map.on('moveend', logEvent);
Такой подход позволяет отслеживать последовательность событий и их взаимосвязь.
Leaflet генерирует множество системных событий карты:
movestartmovemoveendmap.on('moveend', function (e) {
const center = map.getCenter();
console.log('Новый центр:', center);
});
zoomstartzoomzoomendmap.on('zoomend', function () {
console.log('Текущий zoom:', map.getZoom());
});
loadtileloadlayeraddmap.on('load', function () {
console.log('Карта полностью загружена');
});
Каждый слой в Leaflet также является источником событий.
const marker = L.marker([51.5, -0.09]).addTo(map);
marker.on('add', function () {
console.log('Маркер добавлен на карту');
});
marker.on('remove', function () {
console.log('Маркер удалён');
});
marker.on('popupopen', function (e) {
console.log('Попап открыт');
});
marker.on('popupclose', function () {
console.log('Попап закрыт');
});
const polygon = L.polygon([
[51.51, -0.1],
[51.49, -0.08],
[51.5, -0.06]
]).addTo(map);
polygon.on('click', function (e) {
console.log('Клик по полигону');
});
Для анализа источника события используются свойства
target и currentTarget.
map.on('click', function (e) {
console.log(e.target); // карта
});
При работе с группами слоёв важно различать объект-источник:
group.on('click', function (e) {
console.log('Источник события:', e.target);
});
В сложных слоях, таких как L.LayerGroup, событие может
всплывать от вложенных объектов.
group.on('click', function (e) {
console.log('Конечный источник:', e.propagatedFrom || e.target);
});
События могут проходить через цепочку вложенности, сохраняя информацию о первичном источнике.
Leaflet не предоставляет прямого публичного API для просмотра всех обработчиков, однако контроль осуществляется через управление ссылками на функции.
function handleClick(e) {
console.log('click');
}
map.on('click', handleClick);
// проверка наличия логики достигается структурно
map.off('click', handleClick);
Ключевой принцип — идентичность ссылки на функцию.
Использование once позволяет автоматически удалить
обработчик после первого срабатывания.
map.once('click', function (e) {
console.log('Событие выполнится один раз');
});
Такой механизм используется для проверки первичного взаимодействия с картой или инициализации состояния.
События могут быть инициированы вручную через fire, что
позволяет тестировать логику обработки.
map.fire('click', {
latlng: L.latLng(51.5, -0.09)
});
Это используется для проверки реакций системы без реального взаимодействия пользователя.
Проверка событий часто реализуется через условные конструкции внутри обработчиков.
map.on('click', function (e) {
if (!e.latlng) return;
if (e.originalEvent.shiftKey) {
console.log('Shift + click');
}
});
Таким образом происходит разделение логики по условиям события.
Для анализа поведения карты используется универсальный перехватчик:
map.on('*', function (type, e) {
console.log(type, e);
});
Однако в Leaflet отсутствует встроенный wildcard, поэтому аналог реализуется через обёртку:
function attachLogger(map) {
const events = ['click', 'move', 'zoom', 'zoomend', 'moveend'];
events.forEach(eventName => {
map.on(eventName, function (e) {
console.log(eventName, e);
});
});
}
Leaflet поддерживает механизм остановки распространения событий.
map.on('click', function (e) {
L.DomEvent.stopPropagation(e.originalEvent);
});
Также применяется:
L.DomEvent.preventDefault(e.originalEvent);
Контроль распространения позволяет ограничивать влияние событий DOM и Leaflet одновременно.
Для глубокого анализа последовательности используется централизованный журнал событий.
const eventLog = [];
function traceEvent(e) {
eventLog.push({
type: e.type,
time: Date.now(),
latlng: e.latlng
});
}
map.on('click move zoomend moveend', traceEvent);
Такая структура позволяет отслеживать динамику взаимодействия карты.
Каждое взаимодействие с картой начинается как DOM-событие и преобразуется Leaflet в собственный формат.
map.on('click', function (e) {
console.log(e.originalEvent); // MouseEvent
});
Доступ к originalEvent используется для анализа клавиш
модификации и состояния мыши.
Некоторые действия вызывают последовательность событий:
map.on('mousedown mouseup click', function (e) {
console.log(e.type);
});
Анализ последовательности позволяет выявлять конфликтующие обработчики.
Порядок регистрации влияет на последовательность вызовов:
map.on('click', handlerA);
map.on('click', handlerB);
handlerA всегда выполняется раньше
handlerB, если не изменён контекст выполнения через
внутренние механизмы событий.
При создании кастомных слоёв через L.Class или
расширение L.Layer события можно генерировать вручную:
const CustomLayer = L.Layer.extend({
onAdd: function (map) {
this._map = map;
this.fire('added');
}
});
Проверка таких событий осуществляется через стандартную подписку:
layer.on('added', function () {
console.log('Custom event fired');
});