В Google Maps JavaScript API все графические объекты на карте —
маркеры, линии, полигоны, окружности и прямоугольники — построены на
основе событийной модели, позволяющей реагировать на действия
пользователя и изменения состояния объектов в реальном времени.
Обработка событий фигур опирается на единый механизм
google.maps.event, а также на внутренние события самих
MVC-объектов, таких как MVCArray, который используется для
хранения координатных наборов.
Каждая фигура в API наследует поведение, позволяющее регистрировать слушатели событий через:
google.maps.event.addListener(instance, eventName, handler);
или более современную форму:
instance.addListener(eventName, handler);
Оба варианта функционально эквивалентны, однако второй чаще используется в современном коде из-за читаемости и привязки к конкретному объекту.
Удаление обработчиков выполняется через объект слушателя:
const listener = google.maps.event.addListener(polygon, 'click', () => {
console.log('click');
});
google.maps.event.removeListener(listener);
События фигур не блокируют основное выполнение скрипта, но могут влиять на состояние карты и связанные элементы интерфейса, такие как информационные окна или панели редактирования.
Хотя маркеры не являются сложными геометрическими фигурами, они формируют основу событийной модели:
marker.addListener('click', (event) => {
console.log(event.latLng.toString());
});
Событие click передает объект MouseEvent,
содержащий координаты latLng, пиксельные координаты и
ссылку на DOM-событие.
Маркер поддерживает также:
dragstartdragdragendmouseovermouseoutПри включенной опции draggable: true события
перетаскивания становятся ключевыми для обновления состояния
приложения.
Полилинии используют структуру MVCArray для хранения
координат. Это означает, что изменение геометрии можно отслеживать на
уровне массива:
polyline.getPath().addListener('insert_at', (index) => {
console.log('Добавлена точка:', index);
});
polyline.getPath().addListener('set_at', (index) => {
console.log('Изменена точка:', index);
});
polyline.getPath().addListener('remove_at', (index) => {
console.log('Удалена точка:', index);
});
Эти события не относятся к google.maps.event, а являются
частью реактивной модели MVCArray, что делает их особенно
важными при реализации редакторов маршрутов.
Дополнительно сама полилиния поддерживает события:
clickmousemoverightclickПри этом событие mousemove может генерироваться с
высокой частотой, что требует оптимизации обработчиков.
Полигон расширяет модель полилинии, добавляя замкнутую область и возможность работы с внутренними отверстиями (holes). Основные события аналогичны:
polygon.addListener('click', (event) => {
console.log(event.latLng);
});
Особое значение имеет доступ к изменению вершин:
polygon.getPath().addListener('set_at', () => {
console.log('Изменение внешнего контура');
});
Если полигон содержит несколько контуров, каждый из них представлен
отдельным MVCArray, и обработка событий должна учитывать
индекс пути:
polygon.getPaths().forEach((path, index) => {
path.addListener('insert_at', () => {
console.log('Изменение в контуре', index);
});
});
Окружность состоит из двух ключевых параметров: центра и радиуса. События привязаны к маркероподобной модели изменения:
circle.addListener('center_changed', () => {
console.log(circle.getCenter());
});
circle.addListener('radius_changed', () => {
console.log(circle.getRadius());
});
В отличие от полигонов, окружность не использует
MVCArray, но предоставляет прямые события для ключевых
свойств.
Прямоугольник работает через объект LatLngBounds, что
определяет северо-восточную и юго-западную границы.
rectangle.addListener('bounds_changed', () => {
console.log(rectangle.getBounds());
});
Изменение границ может происходить как через API, так и через
интерактивное редактирование, если включен режим
editable.
Практически все фигуры поддерживают стандартные события указателя:
clickdblclickmousedownmouseupmouseovermouseoutmousemoverightclickКаждое событие содержит объект:
{
latLng: LatLng,
domEvent: MouseEvent
}
latLng является основным источником географических
координат, используемых для дальнейших вычислений или построения новых
объектов.
В обработчиках событий значение this не всегда указывает
на ожидаемый объект. В большинстве случаев рекомендуется явно
использовать замыкания:
polygon.addListener('click', function (event) {
console.log(this.getPath());
});
Однако в строгих режимах или при использовании стрелочных функций
this теряет привязку:
polygon.addListener('click', (event) => {
console.log(this); // не polygon
});
Поэтому для доступа к фигуре предпочтительнее использовать внешнюю переменную:
const poly = polygon;
poly.addListener('click', (event) => {
console.log(poly.getPath());
});
При включении editable: true фигуры начинают
генерировать дополнительные события изменения геометрии. Это особенно
важно для интерактивных картографических редакторов.
Для полигона:
const polygon = new google.maps.Polygon({
editable: true,
draggable: true
});
Изменение вершин автоматически вызывает события set_at,
insert_at, remove_at, а также может приводить
к цепочке click и mousemove событий.
Для объектов с включенным draggable доступны
события:
dragstartdragdragendpolygon.addListener('dragend', (event) => {
console.log('Новая позиция фигуры');
});
Для окружностей и прямоугольников перетаскивание влияет на центр или границы соответственно, что приводит к пересчету геометрии в реальном времени.
При построении интерактивных редакторов карт часто комбинируются несколько уровней событий:
MVCArray для отслеживания структурыПример комбинированной логики:
polygon.addListener('click', (e) => {
const path = polygon.getPath();
path.push(e.latLng);
});
polygon.getPath().addListener('set_at', () => {
updateServerState(polygon.getPath().getArray());
});
События mousemove и drag могут
генерироваться десятки раз в секунду. Это требует ограничения частоты
обработки:
let lastUpdate = 0;
polygon.addListener('mousemove', (e) => {
const now = Date.now();
if (now - lastUpdate < 50) return;
lastUpdate = now;
console.log(e.latLng);
});
Такая схема предотвращает перегрузку интерфейса и снижает нагрузку на основной поток.
События фигур могут конфликтовать с событиями карты. Например, клик
по полигону может одновременно вызывать click карты.
Управление этим поведением осуществляется через:
google.maps.event.addListener(polygon, 'click', (e) => {
google.maps.event.trigger(map, 'customClick', e);
});
Таким образом создается цепочка пользовательских событий, позволяющая строить сложные сценарии взаимодействия между слоями карты и графическими объектами.