В Google Maps JavaScript API взаимодействие с картой строится вокруг событий, которые делятся на две большие группы: события объекта карты и DOM-события контейнера карты. Первые генерируются самой картой и её сущностями (маркер, полилиния, прямоугольник), вторые возникают на уровне HTML-элемента, в котором карта рендерится.
Ключевой механизм подписки — функция
google.maps.event.addListener, обеспечивающая привязку
обработчиков к объектам API.
const map = new google.maps.Map(document.getElementById("map"), {
center: { lat: 55.751244, lng: 37.618423 },
zoom: 10
});
google.maps.event.addListener(map, "click", (event) => {
console.log(event.latLng.toString());
});
Карта рендерится внутри обычного DOM-элемента
<div>, но большинство взаимодействий перехватывается
внутренним слоем API. Поэтому важно различать:
click, drag,
zoom_changed)mousedown, mouseup,
mousemove на контейнере)DOM-события работают напрямую с элементом, тогда как события карты абстрагированы и возвращают географические координаты.
const mapDiv = document.getElementById("map");
mapDiv.addEventListener("click", (e) => {
console.log("DOM click:", e.clientX, e.clientY);
});
Такой обработчик не знает географических координат и оперирует пикселями относительно окна браузера.
Срабатывает при клике по карте с возвратом координат
latLng.
map.addListener("click", (event) => {
const lat = event.latLng.lat();
const lng = event.latLng.lng();
});
Двойной клик. Часто используется для зума или пользовательских действий.
map.addListener("dblclick", (event) => {
console.log("Double click at:", event.latLng.toJSON());
});
Срабатывает при движении курсора по карте.
map.addListener("mousemove", (event) => {
console.log(event.latLng.toString());
});
Контекстное меню мыши.
map.addListener("rightclick", (event) => {
console.log("Right click:", event.latLng.toJSON());
});
Срабатывает при изменении центра карты, включая перетаскивание.
map.addListener("center_changed", () => {
console.log("Center changed");
});
Фиксирует изменение уровня масштаба.
map.addListener("zoom_changed", () => {
console.log("Zoom:", map.getZoom());
});
Срабатывает при изменении видимых границ карты.
map.addListener("bounds_changed", () => {
const bounds = map.getBounds();
});
Один из наиболее полезных событий. Срабатывает после завершения всех анимаций и обновлений.
map.addListener("idle", () => {
console.log("Map is stable");
});
Начало перетаскивания карты.
Активное перетаскивание.
Завершение перемещения.
map.addListener("dragstart", () => console.log("Start dragging"));
map.addListener("drag", () => console.log("Dragging"));
map.addListener("dragend", () => console.log("End dragging"));
Несмотря на внутреннюю обработку событий API, контейнер карты остаётся обычным DOM-элементом. Это позволяет навешивать стандартные обработчики:
const mapDiv = document.getElementById("map");
mapDiv.addEventListener("mousedown", (e) => {
console.log("Mouse down on map container");
});
Однако такие события не дают информации о географических координатах и часто конфликтуют с внутренними обработчиками карты.
Google Maps API предоставляет собственный механизм подписки, который предпочтительнее стандартных DOM-обработчиков при работе с картой.
google.maps.event.addListener(map, "mousemove", (event) => {
console.log(event.latLng.lat(), event.latLng.lng());
});
Также существует привязка к DOM-элементам через API:
google.maps.event.addDomListener(mapDiv, "click", () => {
console.log("DOM click via Google API");
});
Этот метод считается устаревшим, но встречается в старых проектах.
События карты возвращают объект, содержащий:
latLng — координаты точкиpixel (в некоторых событиях) — экранные координатыdomEvent — исходное DOM-событиеmap.addListener("click", (event) => {
console.log(event.domEvent); // оригинальный MouseEvent
console.log(event.latLng); // географические координаты
});
Наличие domEvent позволяет связывать низкоуровневую и
географическую модели взаимодействия.
При взаимодействии с картой события часто формируют цепочку:
mousedown)dragstart, click)center_changed,
zoom_changed)idle)Понимание этого порядка важно при построении сложных интерфейсов поверх карты, особенно при комбинировании пользовательских слоёв и стандартных контролов.
События карты не всплывают через DOM-дерево браузера. Они изолированы внутри API и не участвуют в стандартной фазе bubbling/capturing.
DOM-события контейнера, наоборот, работают по классической модели браузера, но могут быть частично перехвачены картой, особенно при взаимодействии с жестами (drag, zoom).
Некоторые события позволяют управлять поведением карты через методы объекта события или конфигурацию карты.
map.addListener("click", (event) => {
event.stop(); // предотвращение дальнейшей обработки
});
Также управление возможно через настройки:
const map = new google.maps.Map(document.getElementById("map"), {
draggable: false,
disableDoubleClickZoom: true
});
Частые события, такие как mousemove, могут вызываться
десятки раз в секунду. Это требует контроля нагрузки:
let lastUpdate = 0;
map.addListener("mousemove", (event) => {
const now = Date.now();
if (now - lastUpdate < 50) return;
lastUpdate = now;
console.log(event.latLng.toJSON());
});
В сложных интерфейсах часто требуется синхронизация DOM-событий и событий карты:
map.addListener("click", (event) => {
const panel = document.getElementById("info");
panel.innerText = `${event.latLng.lat()}, ${event.latLng.lng()}`;
});
mapDiv.addEventListener("mousemove", (e) => {
console.log("Pixel:", e.clientX, e.clientY);
});
Такая связка позволяет одновременно работать с географическими и экранными координатами, разделяя уровни ответственности между DOM и API.