InfoWindow — встроенный компонент Google Maps JavaScript API, предназначенный для отображения информационных окон поверх карты. Обычно используется для вывода сведений о маркерах, объектах инфраструктуры, координатах, результатах поиска и пользовательских данных.
Информационное окно представляет собой всплывающий контейнер, который может содержать:
Окно автоматически позиционируется относительно заданной точки на карте или привязанного маркера.
Для создания информационного окна используется класс
google.maps.InfoWindow.
Простейший пример:
const infoWindow = new google.maps.InfoWindow({
content: "Информация о точке"
});
После создания объект существует в памяти, но не отображается на карте до вызова метода открытия.
Основным параметром является content.
const infoWindow = new google.maps.InfoWindow({
content: "Москва"
});
Результатом станет простое окно с текстом.
Внутри окна может размещаться полноценная HTML-разметка.
const infoWindow = new google.maps.InfoWindow({
content: `
<div>
<h3>Москва</h3>
<p>Столица Российской Федерации.</p>
</div>
`
});
Такой подход используется значительно чаще, поскольку позволяет создавать сложные карточки объектов.
В качестве содержимого можно передавать HTML-элемент.
const container = document.createElement("div");
container.innerHTML = `
<h3>Точка интереса</h3>
<p>Описание объекта</p>
`;
const infoWindow = new google.maps.InfoWindow({
content: container
});
Подход удобен при генерации интерфейса средствами JavaScript.
Для показа окна применяется метод open().
Пример:
infoWindow.open({
map: map
});
После выполнения окно появляется на карте.
InfoWindow может отображаться в произвольных координатах.
const infoWindow = new google.maps.InfoWindow({
content: "Точка на карте",
position: {
lat: 55.7558,
lng: 37.6176
}
});
infoWindow.open({
map: map
});
В данном случае окно не связано с маркером и отображается непосредственно в указанных координатах.
Наиболее распространённый сценарий — показ окна при взаимодействии с маркером.
const marker = new google.maps.Marker({
position: {
lat: 55.7558,
lng: 37.6176
},
map: map
});
const infoWindow = new google.maps.InfoWindow({
content: "Москва"
});
infoWindow.open({
anchor: marker,
map: map
});
Окно будет автоматически располагаться над маркером.
Практически всегда окно отображается после нажатия пользователем на маркер.
marker.addListener("click", () => {
infoWindow.open({
anchor: marker,
map: map
});
});
Такой механизм обеспечивает привычное поведение интерактивной карты.
Контент можно менять после создания окна.
infoWindow.setContent("Новое содержимое");
Либо использовать HTML.
infoWindow.setContent(`
<div>
<strong>Обновлённая информация</strong>
</div>
`);
Это позволяет переиспользовать одно окно для множества объектов.
Для перемещения окна применяется метод
setPosition().
infoWindow.setPosition({
lat: 59.9386,
lng: 30.3141
});
После изменения координат окно можно открыть повторно.
Для скрытия используется метод close().
infoWindow.close();
После вызова окно исчезает с карты, но объект продолжает существовать.
Закрытое окно можно показывать неограниченное количество раз.
infoWindow.close();
infoWindow.open({
anchor: marker,
map: map
});
Создавать новый экземпляр при каждом открытии не требуется.
Создание отдельного InfoWindow для каждого маркера может приводить к лишним затратам памяти. Часто применяется один экземпляр окна, который обновляет содержимое при выборе объекта.
const infoWindow = new google.maps.InfoWindow();
markers.forEach(marker => {
marker.addListener("click", () => {
infoWindow.setContent(marker.title);
infoWindow.open({
anchor: marker,
map: map
});
});
});
Такой подход считается оптимальным для карт с большим количеством объектов.
Часто информация хранится внутри массива объектов.
const places = [
{
name: "Москва",
description: "Столица России",
lat: 55.7558,
lng: 37.6176
},
{
name: "Санкт-Петербург",
description: "Культурная столица",
lat: 59.9386,
lng: 30.3141
}
];
Создание маркеров:
places.forEach(place => {
const marker = new google.maps.Marker({
position: {
lat: place.lat,
lng: place.lng
},
map: map
});
marker.addListener("click", () => {
infoWindow.setContent(`
<div>
<h3>${place.name}</h3>
<p>${place.description}</p>
</div>
`);
infoWindow.open({
anchor: marker,
map: map
});
});
});
Для повышения доступности интерфейса используется параметр
ariaLabel.
const infoWindow = new google.maps.InfoWindow({
content: "Описание объекта",
ariaLabel: "Информация о достопримечательности"
});
Данное описание применяется вспомогательными технологиями и экранными дикторами.
Размер окна можно ограничить через maxWidth.
const infoWindow = new google.maps.InfoWindow({
content: longContent,
maxWidth: 300
});
Если контент превышает указанную ширину, браузер выполнит перенос строк.
Для сохранения структуры интерфейса можно использовать
minWidth.
const infoWindow = new google.maps.InfoWindow({
content: content,
minWidth: 250
});
Особенно полезно при отображении карточек с одинаковым дизайном.
InfoWindow поддерживает собственную систему событий.
Срабатывает при нажатии на кнопку закрытия.
infoWindow.addListener("closeclick", () => {
console.log("Окно закрыто");
});
Вызывается после изменения содержимого.
infoWindow.addListener("content_changed", () => {
console.log("Контент обновлён");
});
Срабатывает после изменения позиции.
infoWindow.addListener("position_changed", () => {
console.log("Позиция изменена");
});
Позволяет определить момент отображения окна.
infoWindow.addListener("visible", () => {
console.log("Окно показано");
});
InfoWindow часто используется для создания мини-карточек.
Пример:
const html = `
<div class="card">
<img
src="images/hotel.jpg"
alt="Отель"
width="250"
>
<h3>Отель Premium</h3>
<p>
Расстояние до центра: 1.2 км
</p>
<a href="/hotel/1">
Подробнее
</a>
</div>
`;
const infoWindow = new google.maps.InfoWindow({
content: html
});
Такой формат широко применяется в сервисах бронирования, навигационных системах и геоинформационных приложениях.
Если используется несколько окон одновременно, карта может быстро стать перегруженной.
Нежелательный вариант:
marker1.addListener("click", () => {
infoWindow1.open({
anchor: marker1,
map: map
});
});
marker2.addListener("click", () => {
infoWindow2.open({
anchor: marker2,
map: map
});
});
Лучше использовать единый экземпляр:
const infoWindow = new google.maps.InfoWindow();
marker.addListener("click", () => {
infoWindow.close();
infoWindow.setContent(data);
infoWindow.open({
anchor: marker,
map: map
});
});
В результате на карте одновременно отображается только одно окно.
При формировании содержимого из пользовательских данных необходимо учитывать риск XSS-атак.
Небезопасный вариант:
infoWindow.setContent(`
<div>${userInput}</div>
`);
Если строка содержит вредоносный HTML или JavaScript, это может привести к компрометации приложения.
Безопаснее использовать предварительную фильтрацию данных либо создавать DOM-элементы программно.
const div = document.createElement("div");
div.textContent = userInput;
infoWindow.setContent(div);
Полный пример карты с маркером и информационным окном:
const map = new google.maps.Map(
document.getElementById("map"),
{
center: {
lat: 55.7558,
lng: 37.6176
},
zoom: 10
}
);
const marker = new google.maps.Marker({
position: {
lat: 55.7558,
lng: 37.6176
},
map: map
});
const infoWindow = new google.maps.InfoWindow({
content: `
<div>
<h3>Москва</h3>
<p>Крупнейший город России.</p>
</div>
`
});
marker.addListener("click", () => {
infoWindow.open({
anchor: marker,
map: map
});
});
В данном примере реализованы основные возможности InfoWindow: создание окна, размещение HTML-контента, привязка к маркеру и отображение по пользовательскому событию.