Маркеры являются интерактивными объектами карты, способными реагировать на действия пользователя и изменения собственного состояния. Обработка событий маркеров позволяет создавать динамические интерфейсы, реализовывать навигацию, отображать дополнительную информацию и организовывать сложное взаимодействие с картографическими данными.
В Google Maps JavaScript API события маркеров реализованы через механизм прослушивателей событий (event listeners), который обеспечивает выполнение пользовательского кода при наступлении определённых действий.
Базовый принцип работы выглядит следующим образом:
marker.addListener("click", () => {
console.log("Маркер нажат");
});
После регистрации обработчика функция будет вызываться каждый раз при возникновении указанного события.
Для регистрации обработчика используется метод
addListener().
Пример создания маркера:
const marker = new google.maps.Marker({
position: {
lat: 55.7558,
lng: 37.6176
},
map: map,
title: "Москва"
});
Добавление обработчика:
marker.addListener("click", () => {
alert("Выбран маркер Москвы");
});
Событие связывается исключительно с данным экземпляром маркера.
Событие click является наиболее распространённым
событием маркеров.
Оно возникает при нажатии левой кнопкой мыши на объект.
marker.addListener("click", () => {
console.log("Клик по маркеру");
});
Типичные сценарии применения:
Пример открытия информационного окна:
const infoWindow = new google.maps.InfoWindow({
content: "<h3>Москва</h3>"
});
marker.addListener("click", () => {
infoWindow.open({
anchor: marker,
map
});
});
Событие dblclick вызывается при двойном щелчке по
маркеру.
marker.addListener("dblclick", () => {
console.log("Двойной клик");
});
Применяется для:
Пример:
marker.addListener("dblclick", () => {
map.setZoom(15);
map.panTo(marker.getPosition());
});
Для обработки нажатия правой кнопкой мыши используется событие
rightclick.
marker.addListener("rightclick", () => {
console.log("Контекстное меню");
});
Часто применяется для:
Пример:
marker.addListener("rightclick", () => {
marker.setMap(null);
});
После выполнения обработчика маркер будет удалён с карты.
Событие возникает в момент нажатия кнопки мыши.
marker.addListener("mousedown", () => {
console.log("Кнопка нажата");
});
Используется для:
Вызывается после отпускания кнопки мыши.
marker.addListener("mouseup", () => {
console.log("Кнопка отпущена");
});
Обычно работает совместно с mousedown.
Событие возникает при наведении указателя мыши на маркер.
marker.addListener("mouseover", () => {
console.log("Наведение");
});
Распространённые сценарии:
Пример увеличения иконки:
marker.addListener("mouseover", () => {
marker.setIcon({
url: "icon-large.png",
scaledSize: new google.maps.Size(50, 50)
});
});
Срабатывает при уходе курсора с маркера.
marker.addListener("mouseout", () => {
console.log("Курсор покинул маркер");
});
Обычно используется для отмены изменений, выполненных в
mouseover.
marker.addListener("mouseout", () => {
marker.setIcon({
url: "icon.png",
scaledSize: new google.maps.Size(32, 32)
});
});
Если маркер является перетаскиваемым, можно отслеживать начало перемещения.
Создание перетаскиваемого маркера:
const marker = new google.maps.Marker({
position: position,
map: map,
draggable: true
});
Обработка начала перемещения:
marker.addListener("dragstart", () => {
console.log("Начало перетаскивания");
});
Полезно для:
Во время перемещения маркера постоянно генерируется событие
drag.
marker.addListener("drag", () => {
console.log("Маркер перемещается");
});
Получение текущих координат:
marker.addListener("drag", () => {
const pos = marker.getPosition();
console.log(
pos.lat(),
pos.lng()
);
});
Событие может вызываться десятки раз в секунду, поэтому тяжёлые вычисления внутри обработчика нежелательны.
Вызывается после завершения перемещения.
marker.addListener("dragend", () => {
console.log("Перетаскивание завершено");
});
Получение новых координат:
marker.addListener("dragend", () => {
const position = marker.getPosition();
console.log(position.lat());
console.log(position.lng());
});
Часто используется для сохранения координат на сервере.
marker.addListener("dragend", async () => {
const position = marker.getPosition();
await fetch("/save-location", {
method: "POST",
body: JSON.stringify({
lat: position.lat(),
lng: position.lng()
})
});
});
Некоторые обработчики получают объект события в качестве параметра.
marker.addListener("click", (event) => {
console.log(event);
});
Объект содержит полезную информацию о произошедшем действии.
Пример:
marker.addListener("click", (event) => {
console.log(event.latLng.lat());
console.log(event.latLng.lng());
});
Координаты позволяют определить точку взаимодействия пользователя.
Вместо анонимных функций допускается применение отдельных обработчиков.
function handleMarkerClick() {
console.log("Маркер выбран");
}
marker.addListener("click", handleMarkerClick);
Преимущества подхода:
Метод addListener() возвращает объект
прослушивателя.
const listener = marker.addListener("click", () => {
console.log("Клик");
});
Удаление:
listener.remove();
Альтернативный вариант:
google.maps.event.removeListener(listener);
После удаления функция больше не будет вызываться.
Иногда требуется полностью очистить объект от событий.
google.maps.event.clearInstanceListeners(marker);
После выполнения будут удалены все обработчики, зарегистрированные для данного маркера.
Для одного события может существовать несколько независимых слушателей.
marker.addListener("click", () => {
console.log("Первый обработчик");
});
marker.addListener("click", () => {
console.log("Второй обработчик");
});
marker.addListener("click", () => {
console.log("Третий обработчик");
});
Все функции будут выполнены последовательно.
События часто используются для изменения визуального состояния объекта.
Пример переключения анимации:
marker.addListener("click", () => {
marker.setAnimation(
google.maps.Animation.BOUNCE
);
});
Остановка анимации через некоторое время:
marker.addListener("click", () => {
marker.setAnimation(
google.maps.Animation.BOUNCE
);
setTimeout(() => {
marker.setAnimation(null);
}, 2000);
});
При создании набора маркеров обработчики обычно назначаются в цикле.
locations.forEach(location => {
const marker = new google.maps.Marker({
position: location.position,
map: map,
title: location.name
});
marker.addListener("click", () => {
console.log(location.name);
});
});
Каждый обработчик получает доступ к данным конкретного объекта.
Замыкания позволяют связывать дополнительные данные с событием.
function createMarker(city) {
const marker = new google.maps.Marker({
position: city.position,
map: map
});
marker.addListener("click", () => {
alert(city.name);
});
return marker;
}
Каждый обработчик сохраняет ссылку на объект города даже после завершения функции.
При большом количестве маркеров удобно использовать единую функцию.
function handleCityClick(city) {
console.log(city.name);
}
locations.forEach(city => {
const marker = new google.maps.Marker({
position: city.position,
map: map
});
marker.addListener("click", () => {
handleCityClick(city);
});
});
Подобная архитектура значительно упрощает поддержку приложения.
Для одного маркера можно организовать комплексное взаимодействие.
marker.addListener("mouseover", () => {
console.log("Наведение");
});
marker.addListener("mouseout", () => {
console.log("Уход курсора");
});
marker.addListener("click", () => {
console.log("Выбор объекта");
});
marker.addListener("dragend", () => {
console.log("Новая позиция");
});
Такой подход позволяет реализовать поведение, характерное для полноценных картографических интерфейсов.
marker.addListener("click", () => {
openPropertyCard(propertyId);
});
marker.addListener("mouseover", () => {
marker.setZIndex(1000);
});
marker.addListener("mouseout", () => {
marker.setZIndex(null);
});
marker.addListener("dragend", () => {
const pos = marker.getPosition();
saveCoordinates({
lat: pos.lat(),
lng: pos.lng()
});
});
marker.addListener("drag", () => {
const pos = marker.getPosition();
latitudeInput.value = pos.lat();
longitudeInput.value = pos.lng();
});
marker.addListener("click", () => {
map.panTo(marker.getPosition());
map.setZoom(16);
});
При работе с большим количеством маркеров следует учитывать особенности событийной системы:
drag;Грамотное использование событий маркеров превращает карту из статического визуального элемента в полноценный интерактивный интерфейс, реагирующий на действия пользователя в режиме реального времени и обеспечивающий удобную работу с географическими данными.