В Google Maps JavaScript API взаимодействие пользователя с картой
строится вокруг событийной модели. Почти каждый объект карты — маркер,
линия, многоугольник, окружность — способен генерировать события, на
которые можно подписаться через механизм addListener.
События делятся на пользовательские (click, drag, mouseover и т.д.) и
внутренние (изменение состояния объектов через методы API).
Основной принцип работы событий заключается в регистрации
обработчиков и управлении их жизненным циклом. Обработчики возвращают
объект MapsEventListener, который позволяет позднее удалить
подписку через removeListener.
Все интерактивные объекты используют единый интерфейс:
google.maps.event.addListener(instance, eventName, handler);
Где:
instance — объект карты или её примитив (Marker,
Polygon, Polyline и др.)eventName — имя событияhandler — функция-обработчикПример:
const marker = new google.maps.Marker({
position: { lat: 55.751244, lng: 37.618423 },
map: map,
title: "Москва"
});
google.maps.event.addListener(marker, "click", (event) => {
console.log("Маркер нажат", event.latLng.toString());
});
Современный синтаксис также допускает:
marker.addListener("click", handler);
Оба варианта эквивалентны, но второй считается более лаконичным.
Маркер — один из наиболее часто используемых объектов карты, и он поддерживает широкий набор событий.
Срабатывает при нажатии на маркер.
marker.addListener("click", () => {
infoWindow.open(map, marker);
});
Двойной клик по маркеру. Используется для альтернативных действий, например масштабирования или редактирования.
marker.addListener("dblclick", () => {
map.setZoom(map.getZoom() + 1);
});
События перетаскивания маркера. Работают только при
draggable: true.
marker.setDraggable(true);
marker.addListener("dragstart", () => {
console.log("Начало перетаскивания");
});
marker.addListener("drag", (event) => {
console.log("Текущая позиция:", event.latLng.toString());
});
marker.addListener("dragend", (event) => {
console.log("Финальная позиция:", event.latLng.toString());
});
Используются для визуального взаимодействия.
marker.addListener("mouseover", () => {
marker.setAnimation(google.maps.Animation.BOUNCE);
});
marker.addListener("mouseout", () => {
marker.setAnimation(null);
});
Контекстное взаимодействие (ПКМ).
marker.addListener("rightclick", (event) => {
console.log("Контекстное меню маркера");
});
Polyline представляет собой ломаную линию, состоящую из набора координат. Она поддерживает интерактивные события аналогично маркерам.
const polyline = new google.maps.Polyline({
path: [
{ lat: 55.75, lng: 37.61 },
{ lat: 55.76, lng: 37.62 }
],
map: map
});
polyline.addListener("click", (event) => {
console.log("Клик по линии в точке:", event.latLng.toString());
});
Используется для отслеживания положения курсора вдоль линии.
polyline.addListener("mousemove", (event) => {
console.log("Курсор над линией:", event.latLng.toString());
});
Polygon позволяет работать с замкнутыми областями и поддерживает расширенный набор взаимодействий.
polygon.addListener("click", (event) => {
console.log("Клик по полигону");
});
Применяются для динамического выделения областей.
polygon.addListener("mouseover", () => {
polygon.setOptions({ fillColor: "#FF0000" });
});
polygon.addListener("mouseout", () => {
polygon.setOptions({ fillColor: "#00FF00" });
});
Используется для контекстных действий внутри области.
Circle представляет географическую зону с центром и радиусом. События работают аналогично polygon.
circle.addListener("click", (event) => {
console.log("Клик по окружности");
});
Хотя circle не является редактируемым по умолчанию, при включении
editable: true можно отслеживать изменения:
circle.setEditable(true);
circle.addListener("radius_changed", () => {
console.log("Радиус изменён:", circle.getRadius());
});
circle.addListener("center_changed", () => {
console.log("Центр изменён:", circle.getCenter().toString());
});
Rectangle поддерживает те же принципы, что и circle, но с привязкой к bounds.
rectangle.addListener("bounds_changed", () => {
console.log("Границы изменены:", rectangle.getBounds());
});
При включении редактирования:
rectangle.setEditable(true);
rectangle.addListener("dragend", () => {
console.log("Прямоугольник перемещён");
});
Многие объекты Google Maps API имеют внутренние события изменения свойств:
position_changed (Marker)zoom_changed (Map)center_changed (Map)visible_changedzindex_changedПример:
marker.addListener("position_changed", () => {
console.log("Новая позиция маркера:", marker.getPosition().toString());
});
Карта сама является крупным источником событий, которые часто комбинируются с событиями объектов.
map.addListener("click", (event) => {
console.log("Клик по карте:", event.latLng.toString());
});
map.addListener("zoom_changed", () => {
console.log("Новый zoom:", map.getZoom());
});
map.addListener("dragstart", () => {
console.log("Начало перемещения карты");
});
map.addListener("dragend", () => {
console.log("Конец перемещения карты");
});
При взаимодействии с геометрическими объектами большинство событий
передают объект MouseEvent, содержащий:
latLng — координаты точки взаимодействияdomEvent — нативное DOM-событие (при наличии)stop() — остановка дальнейшего распространения
событияПример:
marker.addListener("click", (event) => {
console.log(event.latLng.lat(), event.latLng.lng());
});
Каждый вызов addListener возвращает объект подписки:
const listener = marker.addListener("click", () => {
console.log("click");
});
Удаление:
google.maps.event.removeListener(listener);
Очистка всех событий объекта:
google.maps.event.clearInstanceListeners(marker);
Очистка всех глобальных слушателей:
google.maps.event.clearListeners(marker, "click");
События часто используются для синхронизации UI и состояния приложения:
marker.addListener("dragend", (event) => {
updateFormCoordinates(event.latLng);
});
const infoWindow = new google.maps.InfoWindow({
content: "Информация"
});
polygon.addListener("click", (event) => {
infoWindow.setPosition(event.latLng);
infoWindow.open(map);
});
Каждый обработчик сохраняет контекст, что позволяет связывать данные с конкретными объектами:
function createMarker(data) {
const marker = new google.maps.Marker({
position: data.position,
map: map
});
marker.addListener("click", () => {
console.log(data.id);
});
}
Событийная модель Google Maps имеет ряд особенностей:
draggable)При работе с большим количеством маркеров и фигур важно учитывать:
const markers = [];
for (let i = 0; i < 1000; i++) {
const marker = new google.maps.Marker({
position: generatePosition(i),
map: map
});
marker.addListener("click", handleClick);
markers.push(marker);
}
Часто события карты, маркеров и фигур используются совместно для построения сложной логики:
map.addListener("click", (event) => {
const marker = new google.maps.Marker({
position: event.latLng,
map: map
});
marker.addListener("click", () => {
console.log("Маркер создан по клику на карту");
});
});
При работе с несколькими слоями (markers, polygons, overlays) важно учитывать порядок обработки событий. Более специфические объекты (например, маркеры) перехватывают события раньше, чем карта.
Поведение может зависеть от: