Работа с интерактивными элементами на карте в JavaScript-реализации HERE Maps строится вокруг управления состоянием UI-объектов: информационных окон, балунов, всплывающих карточек, кастомных оверлеев и DOM-слоёв, привязанных к географическим координатам. Центральной задачей становится контроль их открытия, закрытия, переключения и синхронизации с событиями карты.
В архитектуре HERE Maps UI каждый всплывающий элемент рассматривается как объект с жизненным циклом:
Ключевое различие между типами элементов заключается в том,
управляются ли они через H.ui.UI (UI-слой) или через
H.map (низкоуровневые объекты карты).
Наиболее распространённый механизм всплывающих окон —
H.ui.InfoBubble. Он используется для отображения
информации, связанной с координатой или объектом карты.
const platform = new H.service.Platform({
apikey: 'API_KEY'
});
const defaultLayers = platform.createDefaultLayers();
const map = new H.Map(
document.getElementById('map'),
defaultLayers.vector.normal.map,
{
zoom: 10,
center: { lat: 52.52, lng: 13.405 }
}
);
const ui = H.ui.UI.createDefault(map, defaultLayers);
const bubble = new H.ui.InfoBubble(
{ lat: 52.52, lng: 13.405 },
{
content: '<div>Точка интереса</div>'
}
);
ui.addBubble(bubble);
Добавление объекта в UI автоматически переводит его в состояние «открыт».
Удаление всплывающего окна выполняется через UI-контейнер:
ui.removeBubble(bubble);
После удаления объект перестаёт участвовать в рендеринге, но может быть повторно использован при повторном добавлении.
Типичная задача — обеспечение поведения «один открыт, остальные закрыты». Для этого требуется хранить ссылку на активное окно.
let activeBubble = null;
function openBubble(position, html) {
if (activeBubble) {
ui.removeBubble(activeBubble);
activeBubble = null;
}
const bubble = new H.ui.InfoBubble(position, {
content: html
});
ui.addBubble(bubble);
activeBubble = bubble;
}
Данная модель исключает накопление открытых окон и снижает нагрузку на UI-слой.
Закрытие всех активных всплывающих элементов часто привязывается к
событию tap у карты:
map.addEventListener('tap', () => {
if (activeBubble) {
ui.removeBubble(activeBubble);
activeBubble = null;
}
});
Такой подход обеспечивает глобальную деактивацию всплывающих окон при взаимодействии с пустой областью карты.
Маркер (H.map.Marker) часто используется как триггер
открытия информационного окна.
const marker = new H.map.Marker({ lat: 52.52, lng: 13.405 });
map.addObject(marker);
marker.addEventListener('tap', (evt) => {
const position = evt.target.getGeometry();
if (activeBubble) {
ui.removeBubble(activeBubble);
}
activeBubble = new H.ui.InfoBubble(position, {
content: '<div>Информация о маркере</div>'
});
ui.addBubble(activeBubble);
});
Здесь управление состоянием становится локальным для каждого объекта карты, но централизуется через переменную состояния.
При работе с несколькими окнами необходимо учитывать поведение UI-слоя:
Для контроля используется массив активных объектов:
const bubbles = [];
function addBubble(position, content) {
const bubble = new H.ui.InfoBubble(position, { content });
ui.addBubble(bubble);
bubbles.push(bubble);
}
function closeAllBubbles() {
bubbles.forEach(b => ui.removeBubble(b));
bubbles.length = 0;
}
В некоторых сценариях требуется обновление содержимого без повторного открытия.
activeBubble.setContent('<div>Обновлённые данные</div>');
Такой подход сохраняет позицию и состояние окна, минимизируя перерисовку UI.
Положение всплывающего окна зависит от геометрии привязки. При динамическом обновлении координат необходимо синхронизировать bubble с новой позицией:
activeBubble.setPosition({ lat: 52.53, lng: 13.41 });
Это особенно важно при работе с движущимися объектами.
Часто требуется скрывать всплывающие окна при zoom-событиях:
map.addEventListener('mapviewchange', () => {
if (activeBubble) {
ui.removeBubble(activeBubble);
activeBubble = null;
}
});
Такое поведение снижает визуальный шум при смене уровня детализации карты.
Помимо InfoBubble, применяются пользовательские
HTML-слои через H.map.DomMarker:
const domIcon = document.createElement('div');
domIcon.innerHTML = '<div class="popup">Контент</div>';
const domMarker = new H.map.DomMarker(
{ lat: 52.52, lng: 13.405 },
{ icon: new H.map.DomIcon(domIcon) }
);
map.addObject(domMarker);
Управление открытием и закрытием в этом случае реализуется вручную через изменение DOM:
domIcon.style.display = 'none'; // закрытие
domIcon.style.display = 'block'; // открытие
При большом количестве объектов используется группировка:
const group = new H.map.Group();
group.addEventListener('tap', (evt) => {
const target = evt.target;
if (target instanceof H.map.Marker) {
openBubble(target.getGeometry(), 'Групповой элемент');
}
});
map.addObject(group);
Группы позволяют централизовать управление событиями и снижать количество обработчиков.
Критическим аспектом становится согласование состояния всплывающих окон с состоянием карты:
function resetUI() {
if (activeBubble) {
ui.removeBubble(activeBubble);
activeBubble = null;
}
}
Повторное открытие окна на той же координате требует либо пересоздания объекта, либо повторной активации:
if (activeBubble && activeBubble.getPosition().equals(position)) {
ui.removeBubble(activeBubble);
activeBubble = null;
} else {
openBubble(position, content);
}
Такой подход предотвращает дублирование окон.
При усложнении логики вводится отдельный контроллер управления всплывающими элементами:
class BubbleController {
constructor(ui) {
this.ui = ui;
this.current = null;
}
open(position, content) {
if (this.current) {
this.ui.removeBubble(this.current);
}
this.current = new H.ui.InfoBubble(position, { content });
this.ui.addBubble(this.current);
}
close() {
if (this.current) {
this.ui.removeBubble(this.current);
this.current = null;
}
}
}
Такой слой абстракции упрощает масштабирование логики UI и уменьшает связанность компонентов.
При удалении или пересоздании карты требуется явная очистка всех UI-объектов:
function disposeMap() {
if (activeBubble) {
ui.removeBubble(activeBubble);
activeBubble = null;
}
map.dispose();
}
Игнорирование этого этапа приводит к утечкам памяти и неконсистентному состоянию интерфейса.
Поведение системы всплывающих окон в HERE Maps сводится к следующим правилам:
Такая модель обеспечивает предсказуемость интерфейса при взаимодействии с геопространственными данными и событиями карты.