Архитектура событий в Google Maps JavaScript API построена на модели
наблюдателя, где большинство объектов (карта, маркеры, оверлеи) могут
как генерировать события, так и реагировать на них через подписку
обработчиков. Основной механизм взаимодействия реализован через
пространство google.maps.event, которое обеспечивает единый
интерфейс работы с событиями независимо от типа объекта.
Ключевая особенность модели заключается в унификации: события карты, маркеров и геометрических объектов обрабатываются одинаковым способом, что упрощает построение сложных интерактивных интерфейсов.
Основной способ привязки логики к событиям — использование
google.maps.event.addListener.
const map = new google.maps.Map(document.getElementById("map"), {
center: { lat: 40.73061, lng: -73.935242 },
zoom: 12
});
google.maps.event.addListener(map, "click", (event) => {
console.log(event.latLng.toString());
});
Каждый обработчик получает объект события, структура которого зависит
от типа источника. В случае карты это обычно объект
MouseEvent, содержащий координаты latLng,
позицию пикселей и дополнительные параметры.
Карты генерируют большое количество событий, наиболее часто используемые:
click — одиночный клик по картеdblclick — двойной кликrightclick — клик правой кнопкойmousemove — движение курсораmousedown и mouseup — нажатие и отпускание
кнопки мышиmap.addListener("click", (e) => {
new google.maps.Marker({
position: e.latLng,
map: map
});
});
center_changed — изменение центра картыzoom_changed — изменение масштабаbounds_changed — изменение границ видимой областиidle — завершение всех анимаций и загрузок тайловmap.addListener("zoom_changed", () => {
console.log("Zoom:", map.getZoom());
});
Событие idle играет важную роль в оптимизации: оно
позволяет выполнять действия после завершения всех перерисовок,
например, загрузку данных для текущей области.
Объекты типа Marker, Polyline,
Polygon, Circle также поддерживают событийную
модель.
const marker = new google.maps.Marker({
position: { lat: 55.75, lng: 37.61 },
map: map
});
marker.addListener("click", () => {
console.log("Marker clicked");
});
Основные события маркеров:
clickdragstartdragdragendПри включённой опции draggable: true маркер становится
интерактивным и генерирует события перемещения.
const polygon = new google.maps.Polygon({
paths: [
{ lat: 55.75, lng: 37.61 },
{ lat: 55.76, lng: 37.62 },
{ lat: 55.74, lng: 37.63 }
],
map: map
});
polygon.addListener("click", (e) => {
console.log(e.latLng);
});
Для геометрических объектов доступны:
clickmousemoverightclickДополнительно у редактируемых объектов появляются события изменения вершин.
При динамическом создании интерфейсов важно управлять жизненным
циклом подписок. Для этого используется
google.maps.event.removeListener.
const listener = map.addListener("click", () => {
console.log("clicked");
});
google.maps.event.removeListener(listener);
Каждый вызов addListener возвращает объект слушателя,
который используется для последующего удаления.
Для сценариев, где обработчик должен сработать только один раз,
используется addListenerOnce.
map.addListenerOnce("idle", () => {
console.log("Map fully loaded and stable");
});
Это особенно полезно при первичной инициализации интерфейса, когда повторное выполнение логики недопустимо.
События мыши и взаимодействия обычно содержат следующие поля:
latLng — географические координатыpixel — позиция в пикселях (в некоторых событиях)domEvent — нативное DOM-событиеmap.addListener("click", (e) => {
console.log(e.latLng.lat(), e.latLng.lng());
});
Объект LatLng предоставляет методы:
lat()lng()toString()Система событий позволяет не только слушать встроенные события, но и
генерировать собственные через
google.maps.event.trigger.
const marker = new google.maps.Marker({
position: { lat: 10, lng: 10 },
map: map
});
marker.addListener("custom_event", (data) => {
console.log("Custom event fired:", data);
});
google.maps.event.trigger(marker, "custom_event", {
id: 1,
message: "Hello"
});
Механизм позволяет строить абстракции поверх стандартных объектов, расширяя их поведение без наследования.
Часто требуется перенаправление событий от одного объекта к другому. Это реализуется через промежуточные обработчики.
map.addListener("click", (e) => {
google.maps.event.trigger(marker, "external_click", e);
});
marker.addListener("external_click", (e) => {
console.log("Forwarded event:", e.latLng);
});
Такой подход используется при создании сложных компонентов, где карта выступает источником событий для UI-слоя.
JavaScript-обработчики событий работают в контексте замыканий, что позволяет сохранять состояние:
function createCounterMarker(map, position) {
let count = 0;
const marker = new google.maps.Marker({
position,
map
});
marker.addListener("click", () => {
count++;
console.log("Clicks:", count);
});
return marker;
}
Каждый маркер хранит собственное состояние, не зависящее от глобальной области видимости.
При большом количестве объектов на карте событийная система становится потенциальным источником нагрузки. Основные факторы:
mousemoveОптимизация достигается через:
idle вместо bounds_changed
для тяжёлых операцийПри массовом количестве объектов применяется подход делегирования: обработчик назначается на контейнер (например, карту), а не на каждый элемент.
map.addListener("click", (e) => {
if (e.placeId) {
console.log("Place clicked");
}
});
Это снижает количество подписок и упрощает управление состоянием интерфейса.
События в API не всегда всплывают по иерархии объектов. Например,
клик по маркеру не всегда приводит к срабатыванию события карты
click. Это важно учитывать при проектировании логики
взаимодействия.
При включённом редактировании геометрии появляются дополнительные события:
insert_atremove_atset_atconst path = polygon.getPath();
path.addListener("set_at", (index) => {
console.log("Vertex changed:", index);
});
Эти события позволяют отслеживать изменения формы объектов в реальном времени.
Событийная модель используется как основной механизм синхронизации UI и состояния карты. Любое изменение — от перемещения центра до редактирования полигона — отражается через события, что позволяет строить реактивные интерфейсы без прямого опроса состояния объектов.