Maps JavaScript API での Web Components 活用(プレビュー)

Web Components は幅広く使用されている W3C 標準で、HTML、CSS、JS をカプセル化して、再利用可能なカスタム HTML 要素として扱えるようにするものです。店舗等の評価を表示するだけの単純な要素から、複雑なビジネス ロジックまで、さまざまな機能をコンポーネントとして再利用することができます。このガイドでは、Maps JavaScript API でご利用いただける Web Components について説明します。

標準そのものの詳細については、Web Components をご覧ください。

対象読者

このドキュメントは、Web Components を使ったアプリケーションの検討と開発を速やかに始められるようにするための資料です。HTML および CSS プログラミングの諸概念についてあらかじめ理解している必要があります。

地図を表示する

Web Components についての学習を始めるには、実例を見るのが一番です。次の例では、サンノゼ周辺の地図を表示しています。

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 ファイル内で宣言することも可能です。

基本地図のスタイルを設定する

マップ ID は、特定の地図のスタイルまたは対象物に関連付けられた識別子です。クラウドを使った設定機能(任意)を活用する場合は、Cloud ベースのマップのスタイル設定の DEMO_MAP_ID を実際のマップ ID に置換します。マップ ID の作成とカスタム スタイルの設定について詳しくは、Cloud ベースのマップのスタイル設定をご覧ください。

地図にマーカーを追加する

組み込みの 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-map> 内に <gmp-advanced-marker> 要素を 2 つ追加しています。title のテキストは、該当要素にマウスオーバー時のテキストとアクセシビリティ用ラベルを追加するものです。

JavaScript イベント

Web Components の大きなメリットのひとつは、手軽に使えることです。JavaScript や高度なプログラミングの知識がそれほどなくても、数行のコードを使用して Google マップを表示できます。実装後のコードの扱いは他の一般的な 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 の読み込み完了時に必要なコールバック機能に対応します。各マーカーに対応するリスナーが作成されており、クリック時に情報ウィンドウが表示されるようになっています。

次のステップ

  • 機能のリクエストと、Maps JavaScript API Issue Tracker のバグの報告を行います。
  • より高位のウェブ コンポーネント(場所の概要など)については Extended Component Library をご覧ください。