Веб-компоненты в Maps JavaScript API (предварительная версия)

Web Components – это популярный стандарт W3C, который позволяет объединять протокол HTML, стили CSS и язык программирования JS в пользовательских элементах HTML, которые можно использовать многократно. Это могут быть крошечные компоненты для конкретной функции, например для показа рейтинга мест, или достаточно сложные фрагменты бизнес-логики. В этом руководстве описаны веб-компоненты, которые доступны в Maps JavaScript API.

Подробные сведения о стандарте можно найти на этой странице.

Аудитория

Эта документация поможет вам быстро изучить веб-компоненты и начать разработку с их использованием. Предполагается, что вы уже знакомы с концепциями использования HTML и CSS.

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

Изучение веб-компонентов лучше начать с простого примера. Ниже вы видите код, который показывает карту района Сан-Хосе.

TypeScript

// This example adds a map using web components.
function initMap(): void {
    console.log('Maps JavaScript API loaded.');
}

declare global {
    interface Window {
        initMap: () => void;
    }
}
window.initMap = initMap;

JavaScript

// This example adds a map using web components.
function initMap() {
  console.log("Maps JavaScript API loaded.");
}

window.initMap = initMap;

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

gmp-map {
  height: 400px;
}

HTML

<html>
  <head>
    <title>Add a Map Web Component</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <gmp-map
      center="37.4220656,-122.0840897"
      zoom="10"
      map-id="DEMO_MAP_ID"
    ></gmp-map>

    <!-- 
      The `defer` attribute causes the callback to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises.
      See https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=beta"
      defer
    ></script>
  </body>
</html>

Примеры кода

В этом примере есть несколько моментов, на которые нужно обратить внимание:

  1. Здесь выполняется асинхронный вызов Maps JavaScript API. Функция обратного вызова позволяет узнать, когда будет получен ответ от API.
  2. Представление карты определяется настраиваемым элементом <gmp-map>.
  3. Свойства карты определяются атрибутами в настраиваемом элементе <gmp-map>.
  4. Стили можно указывать прямо в коде настраиваемых элементов или объявлять в отдельном CSS-файле.

Как настроить стили для базовой карты

Идентификатор карты связан с определенным стилем карты или функцией. Чтобы использовать расширенные возможности конфигурации, замените облачный стиль карты DEMO_MAP_ID собственным идентификатором карты. Узнайте, как создать идентификатор карты и настроить собственный стиль.

Как добавить маркеры к карте

Так же, как и вложенные теги HTML позволяют создавать сложные иерархии контента, размещенные внутри элементов теги <gmp-advanced-marker> позволяют определять маркеры.

TypeScript

// This example adds a map with markers, using web components.
function initMap(): void {
    console.log('Maps JavaScript API loaded.');
}

declare global {
    interface Window {
        initMap: () => void;
    }
}
window.initMap = initMap;

JavaScript

// This example adds a map with markers, using web components.
function initMap() {
  console.log("Maps JavaScript API loaded.");
}

window.initMap = initMap;

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

gmp-map {
  height: 400px;
}

HTML

<html>
  <head>
    <title>Add a Map with Markers using Web Components</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <gmp-map center="43.4142989,-124.2301242" zoom="4" map-id="DEMO_MAP_ID">
      <gmp-advanced-marker
        position="37.4220656,-122.0840897"
        title="Mountain View, CA"
      ></gmp-advanced-marker>
      <gmp-advanced-marker
        position="47.648994,-122.3503845"
        title="Seattle, WA"
      ></gmp-advanced-marker>
    </gmp-map>

    <!-- 
      The `defer` attribute causes the callback to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises.
      See https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&libraries=marker&v=beta"
      defer
    ></script>
  </body>
</html>

Примеры кода

Здесь мы добавили два элемента <gmp-advanced-marker> в пользовательский элемент <gmp-map>. Текст для title определяет информацию, которая появляется при наведении курсора, и метку доступности для указанного элемента.

События JavaScript

Важное преимущество веб-компонентов – простота использования. Всего несколько строк кода позволяют создать карту, не изучая языка JavaScript или сложных методов программирования. Этот код полностью соответствует привычному формату обычных элементов HTML. Например, вы можете использовать встроенную в браузер систему обработки событий, чтобы реагировать на действия (в частности, клики) с картами и расширенными маркерами.

TypeScript

// This example adds a map using web components.
function initMap(): void {
  console.log('Maps JavaScript API loaded.');
  const advancedMarkers = document.querySelectorAll("#marker-click-event-example gmp-advanced-marker");
  for (const advancedMarker of advancedMarkers) {

    customElements.whenDefined(advancedMarker.localName).then(async () => {
      advancedMarker.addEventListener('gmp-click', async () => {

        const infoWindow = new google.maps.InfoWindow({
          //@ts-ignore
          content: advancedMarker.title,
        });
        infoWindow.open({
          //@ts-ignore
          anchor: advancedMarker
        });
      });
    });
  }
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

// This example adds a map using web components.
function initMap() {
  console.log("Maps JavaScript API loaded.");

  const advancedMarkers = document.querySelectorAll(
    "#marker-click-event-example gmp-advanced-marker",
  );

  for (const advancedMarker of advancedMarkers) {
    customElements.whenDefined(advancedMarker.localName).then(async () => {
      advancedMarker.addEventListener("gmp-click", async () => {
        const infoWindow = new google.maps.InfoWindow({
          //@ts-ignore
          content: advancedMarker.title,
        });

        infoWindow.open({
          //@ts-ignore
          anchor: advancedMarker,
        });
      });
    });
  }
}

window.initMap = initMap;

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

gmp-map {
  height: 400px;
}

HTML

<html>
  <head>
    <title>Add a Map Web Component with Events</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <gmp-map
      id="marker-click-event-example"
      center="43.4142989,-124.2301242"
      zoom="4"
      map-id="DEMO_MAP_ID"
    >
      <gmp-advanced-marker
        position="37.4220656,-122.0840897"
        title="Mountain View, CA"
      ></gmp-advanced-marker>
      <gmp-advanced-marker
        position="47.648994,-122.3503845"
        title="Seattle, WA"
      ></gmp-advanced-marker>
    </gmp-map>

    <!-- 
      The `defer` attribute causes the callback to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises.
      See https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&libraries=marker&v=beta"
      defer
    ></script>
  </body>
</html>

Примеры кода

В примере выше initMap представляет собой функцию обратного вызова, которая выполняется после завершения загрузки Maps JavaScript API. Этот код создает для каждого маркера прослушиватели, которые выводят информационное окно при нажатии на определенный маркер.

Что дальше