События маркеров

В экосистеме HERE Technologies работа с маркерами в HERE Maps API построена на событийной модели, основанной на унифицированной системе H.mapevents. Каждый маркер (H.map.Marker) способен генерировать пользовательские события: наведение, клик, касание, перетаскивание, а также низкоуровневые pointer-события.

События не привязаны напрямую к DOM — они транслируются через слой карты, что позволяет одинаково обрабатывать взаимодействие как на desktop, так и на mobile устройствах.


Добавление событий к маркеру

Базовая модель взаимодействия строится вокруг метода addEventListener. Каждый маркер является объектом, поддерживающим интерфейс событий.

const marker = new H.map.Marker({ lat: 52.5200, lng: 13.4050 });

marker.addEventListener('tap', function (evt) {
    console.log('Маркер нажат');
});

Событие tap является универсальным и используется вместо click для поддержки сенсорных устройств.

Для десктопного поведения также доступен pointerdown, но в большинстве случаев рекомендуется использовать высокоуровневые события API.


Контекст события и объект данных

Каждое событие передаёт объект evt, содержащий полезную информацию:

  • target — объект, вызвавший событие (маркер)
  • currentPointer — координаты указателя
  • type — тип события
  • target.getGeometry() — географические координаты маркера
marker.addEventListener('tap', function (evt) {
    const coords = evt.target.getGeometry();
    console.log(coords.lat, coords.lng);
});

Это позволяет строить интерактивные сценарии без обращения к DOM-слою.


Передача пользовательских данных через маркер

Маркер может хранить произвольные данные через setData. Это ключевой механизм связывания географического объекта с бизнес-логикой.

marker.setData({
    id: 42,
    title: 'Офис',
    type: 'branch'
});

marker.addEventListener('tap', function (evt) {
    const data = evt.target.getData();
    console.log(data.title);
});

Такой подход часто используется для отображения всплывающих окон и карточек объектов.


Работа с всплывающими окнами через события

Наиболее распространённый сценарий — открытие информационного окна при клике на маркер.

const bubble = new H.ui.InfoBubble({ lat: 52.5200, lng: 13.4050 }, {
    content: 'Информация об объекте'
});

marker.addEventListener('tap', function (evt) {
    ui.addBubble(bubble);
});

Событие выступает триггером для UI-слоя, при этом логика отображения полностью отделена от маркера.


Перетаскивание маркеров и drag-события

Для включения drag-интеракции требуется активация поведения карты через H.mapevents.Behavior.

const beh * avior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));

После этого маркер можно сделать перетаскиваемым:

marker.draggable = true;

Далее обрабатываются события:

marker.addEventListener('dragstart', function (evt) {
    console.log('Начало перетаскивания');
});

marker.addEventListener('drag', function (evt) {
    const pointer = evt.currentPointer;
    marker.setGeometry(pointer);
});

marker.addEventListener('dragend', function (evt) {
    console.log('Перетаскивание завершено');
});

Ключевой момент заключается в том, что координаты маркера обновляются вручную на основе позиции указателя.


Делегирование событий через карту

Вместо подписки на каждый маркер можно использовать централизованный обработчик на уровне карты:

map.addEventListener('tap', function (evt) {
    if (evt.target instanceof H.map.Marker) {
        console.log('Клик по маркеру');
    }
});

Такой подход эффективен при работе с большим количеством объектов, особенно при динамической генерации маркеров.


Низкоуровневые pointer-события

Система событий поддерживает унифицированные pointer-события:

  • pointerdown
  • pointerup
  • pointermove
  • pointerenter
  • pointerleave
marker.addEventListener('pointerenter', function () {
    console.log('Курсор наведён на маркер');
});

Эти события полезны при создании кастомных эффектов подсветки и анимаций.


Удаление обработчиков событий

Каждый обработчик можно удалить через removeEventListener. Важно сохранять ссылку на функцию.

function onTap(evt) {
    console.log('tap');
}

marker.addEventListener('tap', onTap);
marker.removeEventListener('tap', onTap);

При динамическом создании маркеров это критично для предотвращения утечек памяти.


Особенности поведения событий

Событийная модель имеет ряд особенностей:

  • события не всплывают по DOM-иерархии;
  • порядок обработки зависит от слоя карты;
  • pointer-события могут конфликтовать с поведением карты (pan/zoom);
  • drag требует активированного Behavior.

Взаимодействие с поведением карты

При включённом Behavior часть событий перехватывается системой управления картой. Например, перетаскивание карты может блокировать drag маркера.

const beh * avior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
behavior.disable(H.mapevents.Behavior.DRAGGING);

Это позволяет разделять сценарии взаимодействия между картой и объектами.


Производительность при большом количестве событий

При работе с тысячами маркеров важно учитывать нагрузку:

  • избегать привязки тяжёлых обработчиков к каждому маркеру;
  • использовать делегирование событий через карту;
  • минимизировать создание замыканий в циклах;
  • переиспользовать функции обработчиков.
function handleTap(evt) {
    const marker = evt.target;
    const data = marker.getData();
}

Комбинирование событий и кластеризации

При использовании кластеров события часто перенаправляются на кластерный объект вместо отдельного маркера. В этом случае требуется проверка типа объекта:

map.addEventListener('tap', function (evt) {
    if (evt.target.getData && evt.target.getData().cluster) {
        console.log('Кластер');
    }
});

Такой подход позволяет различать агрегированные и одиночные объекты без изменения архитектуры событийной системы.


Типичные сценарии обработки взаимодействия

Часто используемые комбинации событий:

  • tap → открытие информационного окна
  • pointerenter → подсветка маркера
  • drag → изменение геометрии объекта
  • dragend → сохранение координат на сервере
marker.addEventListener('dragend', function (evt) {
    const coords = evt.target.getGeometry();
    saveToServer(coords);
});

События формируют основу интерактивной модели геоприложений, где каждый маркер выступает автономным интерактивным объектом, управляемым через единый событийный механизм.