イベント

  1. 概要
    1. UI イベント
    2. MVC の状態変化
  2. イベント処理
    1. 例:マップとマーカー イベント
    2. 例:図形の編集とドラッグ イベント
  3. UI イベントの引数にアクセスする
  4. イベント リスナでクロージャを使う
  5. イベント ハンドラ内でのプロパティの取得と設定
  6. DOM イベントをリスニングする
  7. イベントリスナを削除する

概要

ブラウザ内の JavaScript はイベント駆動型です。そのため、JavaScript はイベントを生成することでインタラクションに応答し、プログラムが対象のイベントをリスニングするのことを想定しています。イベントには、以下の 2 つのタイプがあります。

  • ユーザー イベント(マウスの「クリック」イベントなど)は、DOM から Google Maps API に通知されます。これらのイベントは、標準の DOM イベントとは別のものとして区別されます。
  • MVC の状態変化の通知は、Maps API オブジェクトの変化を反映しており、これには property_changed 規則に基づいて名前が付けられています。

各 Maps API オブジェクトは、多くの名前付きイベントをエクスポートします。特定のイベントに関連するプログラムは、それらのイベントに対して JavaScript のイベントリスナを登録します。そして、google.maps.event 名前空間で addListener() イベント ハンドラを登録することで、これらのイベントが受信されたときに、コードが実行されるようにします。

以下のサンプルは、マップとインタラクションを行うと、google.maps.Map によって、どのイベントがトリガーされるのかを示します。

全イベントの一覧は Maps API リファレンスでご確認ください。イベントの一覧は、イベントが属しているオブジェクトごとに収録されています。

UI イベント

Maps API に含まれるオブジェクトの中には、マウスやキーボード イベントのようなユーザー イベントに応答するよう設計されているものがあります。たとえば、google.maps.Marker オブジェクトの場合にリスニングできるユーザー イベントの一部を次に示します。

  • 'click'
  • 'dblclick'
  • 'mouseup'
  • 'mousedown'
  • 'mouseover'
  • 'mouseout'

全リストは、Marker クラスの説明をご覧ください。これらのイベントは標準の DOM イベントに似ていますが、実際は Maps API の一部です。ブラウザごとに実装している DOM イベントモデルは違うため、さまざまなクロスブラウザ特性に対応しなくても、DOM イベントをリスニングしたり、応答したりできる仕組みを Maps API は備えています。また、通常、これらのイベントは、UI 状態(マウスの位置など)を通知するイベントの中で引数を渡します。

MVC の状態変化

通常、MVC オブジェクトは状態を保持します。オブジェクトのプロパティが変化するたびに、API はプロパティが変化したというイベントを発行します。たとえば API は、地図のズーム レベルが変化すると、地図の zoom_changed イベントを発行します。これらの状態変化をインターセプトするには、event 名前空間のメソッドに addListener() イベント ハンドラを登録します。

ユーザー イベントと MVC 状態変化イベントは似ていますが、コード内では別々に扱うのが一般的です。たとえば、MVC イベント内では引数を渡しません。MVC の状態変化に応じて変化したプロパティを確認するには、そのオブジェクトの適切な getProperty メソッドを呼び出します。

イベント処理

イベント通知を登録するには、addListener() イベント ハンドラを使用します。このメソッドは引数として、オブジェクト、リスニングするイベント、指定のイベントが発生した際に呼び出す関数を取ります。

例:マップとマーカー イベント

以下のコードには、ユーザー イベントと状態変化イベントが両方含まれています。クリック時にマップをズームするマーカーに対して、イベントハンドラをアタッチします。さらに center プロパティの変化を検出するイベントハンドラもマップに追加し、center_changed イベントを受信すると、その 3 秒後にマップをマーカーの位置へ戻すようにします。

function initMap() {
  var myLatlng = {lat: -25.363, lng: 131.044};

  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 4,
    center: myLatlng
  });

  var marker = new google.maps.Marker({
    position: myLatlng,
    map: map,
    title: 'Click to zoom'
  });

  map.addListener('center_changed', function() {
    // 3 seconds after the center of the map has changed, pan back to the
    // marker.
    window.setTimeout(function() {
      map.panTo(marker.getPosition());
    }, 3000);
  });

  marker.addListener('click', function() {
    map.setZoom(8);
    map.setCenter(marker.getPosition());
  });
}

例を見る(event-simple.html)

ヒント:ビューポートの変更を検出したい場合は、指定の bounds_changed イベントを使用してください。その構成要素である zoom_changedcenter_changed イベントは使用しないでください。Maps API は、後者の 2 つのイベントを別々に発行するため、ビューポートが正しく変更されるまで、getBounds() は有用な結果を報告しない可能性があります。そのようなイベントの後で getBounds() を使用したい場合は、代わりに bounds_changed イベントをリスニングしてください。

例:図形の編集とドラッグ イベント

図形が編集されたり、ドラッグされたりすると、アクションの完了時にイベントが発行されます。イベントの一覧とコードスニペットについては、図形の説明をご覧ください。

例を見る(rectangle-event.html)

UI イベントの引数にアクセスする

Google Maps API V3 の UI イベントは通常、イベント発生時の UI の状態を通知するイベントの引数を渡します。イベントリスナはこの引数にアクセスできます。たとえば、UI 'click' イベントは通常、マップ上でクリックされた位置を示す latLng プロパティを含む MouseEvent を渡します。この動作は UI イベントに固有で、MVC の状態変化では引数をイベントで渡さないことに注意してください。

イベントリスナ内にあるイベントの引数にアクセスする方法は、オブジェクトのプロパティにアクセスする方法と同じです。以下の例は、マップにイベントリスナを追加して、ユーザーがマップをクリックすると、その位置にマーカーを作成します。

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 4,
    center: {lat: -25.363882, lng: 131.044922 }
  });

  map.addListener('click', function(e) {
    placeMarkerAndPanTo(e.latLng, map);
  });
}

function placeMarkerAndPanTo(latLng, map) {
  var marker = new google.maps.Marker({
    position: latLng,
    map: map
  });
  map.panTo(latLng);
}

例を見る(event-arguments.html)

イベント リスナでクロージャを使う

イベント リスナを実行するとき、通常は、オブジェクトにプライベート データと永続データの両方をアタッチするのが有効です。JavaScript は「プライベート」のインスタンス データはサポートしていませんが、内部関数から外部変数へのアクセスを可能にするクロージャはサポートしています。クロージャは、イベントが発生したオブジェクトには通常アタッチされていない変数に、イベントリスナ内でアクセスするのに便利です。

以下の例では、イベントリスナ内で関数クロージャを使用して、マーカーのセットに秘密のメッセージを割り当てています。各マーカーをクリックすると、そのマーカー自体には含まれていない秘密のメッセージが一部表示されます。

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 4,
    center: {lat: -25.363882, lng: 131.044922 }
  });

  var bounds = {
    north: -25.363882,
    south: -31.203405,
    east: 131.044922,
    west: 125.244141
  };

  // Display the area between the location southWest and northEast.
  map.fitBounds(bounds);

  // Add 5 markers to map at random locations.
  // For each of these markers, give them a title with their index, and when
  // they are clicked they should open an infowindow with text from a secret
  // message.
  var secretMessages = ['This', 'is', 'the', 'secret', 'message'];
  var lngSpan = bounds.east - bounds.west;
  var latSpan = bounds.north - bounds.south;
  for (var i = 0; i < secretMessages.length; ++i) {
    var marker = new google.maps.Marker({
      position: {
        lat: bounds.south + latSpan * Math.random(),
        lng: bounds.west + lngSpan * Math.random()
      },
      map: map
    });
    attachSecretMessage(marker, secretMessages[i]);
  }
}

// Attaches an info window to a marker with the provided message. When the
// marker is clicked, the info window will open with the secret message.
function attachSecretMessage(marker, secretMessage) {
  var infowindow = new google.maps.InfoWindow({
    content: secretMessage
  });

  marker.addListener('click', function() {
    infowindow.open(marker.get('map'), marker);
  });
}

例を見る(event-closure.html)

イベント ハンドラ内でのプロパティの取得と設定

Maps API イベント システム内の MVC 状態変化イベントはすべて、イベントがトリガーされた際に引数を渡しません(ユーザー イベントは検査可能な引数を渡します)。MVC 状態変化のプロパティを検査する必要がある場合は、そのオブジェクトの適切な getProperty() メソッドを明示的に呼び出す必要があります。この検査では常に、MVC オブジェクトの最新状態が取得されますが、これは、イベントが最初に発生したときの状態と一致するとは限りません。

:ある特定のプロパティの状態変化に応答するイベント ハンドラ内で、プロパティを明示的に設定すると、予想外の動作や期待とは異なる動作が生じることがあります。たとえば、そのようなプロパティを設定すると新しいイベントが発生して、そのイベント ハンドラ内で必ずプロパティを設定していると無限ループに陥ることがあります。

以下の例では、ズームイベントに応答するイベント ハンドラを設定し、そのレベルを情報ウィンドウに表示します。

function initMap() {
  var originalMapCenter = new google.maps.LatLng(-25.363882, 131.044922);
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 4,
    center: originalMapCenter
  });

  var infowindow = new google.maps.InfoWindow({
    content: 'Change the zoom level',
    position: originalMapCenter
  });
  infowindow.open(map);

  map.addListener('zoom_changed', function() {
    infowindow.setContent('Zoom: ' + map.getZoom());
  });
}

例を見る(event-properties.html)

DOM イベントをリスニングする

Google Maps JavaScript API イベントモデルは、独自のカスタム イベントを作成および管理します。一方、ブラウザ内の DOM(ドキュメント オブジェクト モデル)も、使用している特定のブラウザ イベント モデルに応じて独自のイベントを作成して送信します。これらのイベントを取得し、応答したい場合は、Maps API が提供する addDomListener() 静的メソッドを使用して、DOM イベントのリスニングとバインドを行います。

この便利なメソッドには、以下のシグネチャがあります。

addDomListener(instance:Object, eventName:string, handler:Function)

instance は、ブラウザがサポートする任意の DOM 要素で、次のようなものが含まれます。

  • windowdocument.body.myform などの DOM の階層構造のメンバー
  • document.getElementById("foo") などの名前の付いた要素

addDomListener() が指定されたイベントをブラウザに渡すと、ブラウザはそのイベントを、ブラウザの DOM イベント モデルに従って処理します。なお、最新ブラウザの多くは、最低でも DOM レベル 2 をサポートしています。(DOM レベルのイベントの詳細は、Mozilla DOM レベルを参照してください)。

このドキュメントでは、DOM イベントの 1 つである window.onload イベントを <body> タグの中で処理しています。このイベントを以下のように使うと、HTML ページが完全に読み込まれたときに、最初の JavaScript コードがトリガーされます。

<script>
  function initialize() {

    // Map initialization

  }
</script>
<body onload="initialize()">
  <div id="map"></div>
</body>

ここでは、このイベントは <body> 要素にアタッチされています。ただし、これは実際には window イベントで、window 要素の下にある DOM 階層の作成とレンダリングが完了したことを示します。

<body> タグ内に onload イベントを含めるとわかりやすくなりますが、そうするとコンテンツと動作が混ざることになります。一般的には、動作コード(JavaScript)からコンテンツ コード(HTML)を分離し、プレゼンテーションのコード(CSS)も別に用意することをお勧めします。そのためには以下のように、Maps API JavaScript コード内にある、インラインの onload イベント ハンドラを DOM リスナで置き換えます。

<script>
  function initialize() {

    // Map initialization

  }

  google.maps.event.addDomListener(window, 'load', initialize);
</script>
<body>
  <div id="map"></div>
</body>

例を見る(event-domListener.html)

上記のコードは Maps JavaScript API のコードですが、addDomListener() メソッドはブラウザの window オブジェクトとバインドされています。そのため API は、API の通常のドメイン外でオブジェクトと情報をやり取りできます。

イベントリスナを削除する

指定したイベントリスナを削除するには、変数を割り当てる必要があります。そして removeListener() を呼び出し、そのリスナに割り当てられた変数名を渡します。

var listener1 = google.maps.event.addListener(marker, 'click', aFunction);

google.maps.event.removeListener(listener1);

特定のインスタンスにあるリスナをすべて削除するには、clearInstanceListeners() を呼び出して、インスタンス名を渡します。

var listener1 = google.maps.event.addListener(marker, 'click', aFunction);
var listener2 = google.maps.event.addListener(marker, 'mouseover', bFunction);

// Remove listener1 and listener2 from marker instance.
google.maps.event.clearInstanceListeners(marker);

特定のインスタンスに対する、指定したイベントタイプのリスナをすべて削除するには、clearListeners() を呼び出して、インスタンス名とイベント名を渡します。

marker.addListener('click', aFunction);
marker.addListener('click', bFunction);
marker.addListener('click', cFunction);

// Remove all click listeners from marker instance.
google.maps.event.clearListeners(marker, 'click');

詳しくは、google.maps.event 名前空間のドキュメントをご覧ください。

フィードバックを送信...

Google Maps JavaScript API
Google Maps JavaScript API
ご不明な点がありましたら、Google のサポートページをご覧ください。