Открытие и закрытие окон

Информационные окна (InfoWindow) в Google Maps JavaScript API используются для отображения дополнительной информации поверх карты. Они позволяют показывать текст, HTML-разметку, изображения, ссылки и другие элементы интерфейса, связанные с конкретной географической точкой или объектом карты.

Наиболее распространённые сценарии применения:

  • отображение информации о маркере;
  • показ адреса или координат;
  • вывод описания объекта;
  • отображение карточек организаций;
  • создание всплывающих интерфейсов взаимодействия.

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


Создание информационного окна

Для создания окна используется класс google.maps.InfoWindow.

Простейший пример:

const infoWindow = new google.maps.InfoWindow({
    content: "Информация о местоположении"
});

Параметр content определяет содержимое окна.

После создания окно ещё не отображается на карте. Для его показа необходимо вызвать метод open().


Открытие окна

Открытие выполняется методом:

infoWindow.open({
    map: map,
    anchor: marker
});

Здесь:

  • map — объект карты;
  • anchor — объект, относительно которого позиционируется окно.

Полный пример:

const marker = new google.maps.Marker({
    position: {
        lat: 55.751244,
        lng: 37.618423
    },
    map: map
});

const infoWindow = new google.maps.InfoWindow({
    content: "Москва"
});

infoWindow.open({
    map: map,
    anchor: marker
});

После выполнения кода окно будет отображено над маркером.


Открытие по щелчку на маркере

Наиболее часто окно открывается при нажатии на маркер.

const marker = new google.maps.Marker({
    position: {
        lat: 55.751244,
        lng: 37.618423
    },
    map: map
});

const infoWindow = new google.maps.InfoWindow({
    content: "Красная площадь"
});

marker.addListener("click", () => {
    infoWindow.open({
        anchor: marker,
        map: map
    });
});

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


Открытие окна без маркера

Информационное окно может быть привязано непосредственно к координатам.

const infoWindow = new google.maps.InfoWindow({
    content: "Точка интереса",
    position: {
        lat: 55.751244,
        lng: 37.618423
    }
});

infoWindow.open(map);

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


Изменение содержимого перед открытием

Содержимое окна можно менять динамически.

const infoWindow = new google.maps.InfoWindow();

marker.addListener("click", () => {

    infoWindow.setContent(`
        <div>
            <h3>Офис компании</h3>
            <p>Время работы: 09:00–18:00</p>
        </div>
    `);

    infoWindow.open({
        map: map,
        anchor: marker
    });
});

Метод:

infoWindow.setContent()

заменяет текущее содержимое новым.


Использование HTML внутри окна

Свойство content поддерживает полноценную HTML-разметку.

const infoWindow = new google.maps.InfoWindow({
    content: `
        <div class="popup">
            <h2>Музей</h2>
            <p>Исторический центр города</p>
            <a href="#">Подробнее</a>
        </div>
    `
});

Можно использовать:

  • заголовки;
  • таблицы;
  • изображения;
  • формы;
  • кнопки;
  • пользовательские компоненты.

Пример с изображением:

const infoWindow = new google.maps.InfoWindow({
    content: `
        <div>
            <img
                src="museum.jpg"
                width="250"
                alt="Музей"
            >
            <h3>Музей истории</h3>
        </div>
    `
});

Повторное открытие уже существующего окна

Один экземпляр InfoWindow может многократно открываться и закрываться.

const infoWindow = new google.maps.InfoWindow({
    content: "Объект"
});

marker1.addListener("click", () => {

    infoWindow.setContent("Первый объект");

    infoWindow.open({
        map: map,
        anchor: marker1
    });
});

marker2.addListener("click", () => {

    infoWindow.setContent("Второй объект");

    infoWindow.open({
        map: map,
        anchor: marker2
    });
});

Подход позволяет избежать создания большого количества объектов InfoWindow.


Закрытие окна

Для закрытия используется метод:

infoWindow.close();

Пример:

button.addEventListener("click", () => {
    infoWindow.close();
});

После вызова окно удаляется с карты, но объект остаётся доступным для повторного открытия.


Автоматическое закрытие пользователем

По умолчанию каждое информационное окно содержит кнопку закрытия.

Пользователь может нажать на крестик в правом верхнем углу окна.

Дополнительный код не требуется.


Закрытие одного окна перед открытием другого

При большом количестве маркеров рекомендуется использовать единственное информационное окно.

const infoWindow = new google.maps.InfoWindow();

markers.forEach(marker => {

    marker.addListener("click", () => {

        infoWindow.close();

        infoWindow.setContent(marker.title);

        infoWindow.open({
            map: map,
            anchor: marker
        });
    });

});

Такой подход предотвращает накопление нескольких открытых окон одновременно.


Отслеживание открытия окна

Для контроля жизненного цикла предусмотрены события.

Событие открытия содержимого:

infoWindow.addListener("domready", () => {
    console.log("Окно отображено");
});

Событие вызывается после создания DOM-элементов внутри окна.

Это удобно для:

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

Отслеживание закрытия окна

Для обработки закрытия применяется событие:

infoWindow.addListener("closeclick", () => {
    console.log("Окно закрыто");
});

Событие возникает после нажатия пользователем кнопки закрытия.

Пример:

infoWindow.addListener("closeclick", () => {

    marker.setAnimation(
        google.maps.Animation.DROP
    );

});

Программное переключение между окнами

Часто требуется отображать различные данные в одном окне.

const infoWindow = new google.maps.InfoWindow();

function showLocation(marker, data) {

    infoWindow.setContent(`
        <div>
            <h3>${data.title}</h3>
            <p>${data.description}</p>
        </div>
    `);

    infoWindow.open({
        map,
        anchor: marker
    });

}

Использование единственного экземпляра уменьшает потребление памяти и повышает производительность.


Проверка состояния окна

Google Maps API не предоставляет метода вроде:

isOpen()

Поэтому состояние обычно хранится самостоятельно.

Пример:

let opened = false;

marker.addListener("click", () => {

    infoWindow.open({
        map,
        anchor: marker
    });

    opened = true;
});

infoWindow.addListener("closeclick", () => {
    opened = false;
});

Такой механизм полезен при реализации сложной логики интерфейса.


Закрытие окна при клике по карте

Часто требуется скрывать окно после щелчка по свободной области карты.

map.addListener("click", () => {
    infoWindow.close();
});

Поведение напоминает работу большинства картографических сервисов.


Переключение открытия и закрытия одним кликом

Можно реализовать режим переключателя.

let opened = false;

marker.addListener("click", () => {

    if (opened) {

        infoWindow.close();
        opened = false;

    } else {

        infoWindow.open({
            map,
            anchor: marker
        });

        opened = true;
    }

});

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


Открытие окна после загрузки карты

Информационное окно может отображаться автоматически сразу после создания карты.

const infoWindow = new google.maps.InfoWindow({
    content: "Добро пожаловать"
});

google.maps.event.addListenerOnce(
    map,
    "idle",
    () => {

        infoWindow.open({
            map,
            anchor: marker
        });

    }
);

Событие idle гарантирует завершение первоначальной отрисовки карты.


Управление несколькими окнами

Если необходимо поддерживать множество независимых окон, их можно хранить в коллекции.

const windows = [];

locations.forEach(location => {

    const infoWindow =
        new google.maps.InfoWindow({
            content: location.name
        });

    windows.push(infoWindow);

});

Для закрытия всех окон одновременно:

windows.forEach(window => {
    window.close();
});

Подход полезен в административных панелях и системах мониторинга.


Практические рекомендации

Использовать один InfoWindow для множества маркеров

Наиболее эффективная схема:

const infoWindow =
    new google.maps.InfoWindow();

с последующим обновлением содержимого через:

infoWindow.setContent(...)

и открытием через:

infoWindow.open(...)

Закрывать окно перед повторным открытием

infoWindow.close();

Это помогает избежать визуальных артефактов и конфликтов позиционирования.

Подключать обработчики через события

Наиболее полезные события:

domready
closeclick

Они позволяют контролировать жизненный цикл окна и взаимодействовать с его содержимым.

Использовать HTML-шаблоны

Вместо длинных строк:

content: "Название"

предпочтительно применять полноценную HTML-разметку:

content: `
    <div class="card">
        ...
    </div>
`

Это упрощает поддержку интерфейса и делает содержимое информационных окон более гибким.