Google Maps API Version3 イベント

Map イベント 概要

ブラウザ内のJavaScriptは イベント駆動型で動作します。つまり、JavaScript では操作に対してイベントを作り、プログラムは目的のイベントを「リッスン」します。たとえばブラウザ内では、ユーザーのマウスとキーボードの操作によって、DOM 内に反映されるイベントが生成されます。 Google Maps API version 3 のイベントモデルは、API Version 2に似ていますが、その下では多くの変更があります。2 つのイベントタイプがあります。

  • ユーザーイベント (マウスイベント"click"のような) はDOMからGoogle Maps APIに伝播されます。それらのイベントは標準的なDOMイベントと別々に異なっています。
  • "property_changed コンビネーション"と名づけられた、Maps API オブジェクトのMVC 状態変化を通知するイベントです。

各Maps API オブジェクトはイベントを発生します。プログラムは必要のあるイベントをJavaScriptのイベントリスナを使って登録することができ、イベントが発生したときに処理を行なうことができます。イベントリスナは google.maps.event 名前空間の addListener() を使って登録することができます。Google Maps API v2の開発者にとってはおなじみの方法です。

イベントリストの一覧は Maps API リファレンスに用意されています。イベントは各オブジェクトに含まれるイベントごとに分かれています。

UI イベント

Maps APIの中のいくつかのオブジェクトは、マウスやキーボードイベントのようなユーザーイベントに反応するように設計されています。例えば、google.maps.Marker オブジェクトは以下のユーザーイベントを監視することができます。

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

これらのイベントは標準的なDOMイベントのように見えますが、実はMaps APIの一部です。なぜなら異なったブラウザが異なったDOMイベントモデルを実装するので、Maps APIでは様々なクロスブラウザの特徴を扱う必要はなく、DOMイベントを監視し反応させるメカニズムを提供します。これらのイベントにも(マウスの位置のような)典型的なUIステートが引数として渡されます。

MVC 状態変化

MVCオブジェクトは一般的にstate (状態)を持っています。オブジェクトのプロパティが変更したときは、APIはプロパティ変更通知イベント(property_changed イベント)を発生します。例えば、地図のズームレベルが変更されると、zoom_changed イベントが発生します。状態変化はevent 名前空間の addListener() メソッドを使ってイベントハンドルを登録すると、受け取ることができます。

UIイベントとMVC状態変化イベントは似ているように見えますが、大抵の場合はコードの中での取り扱い方が異なります。例えば、MVCイベントはイベントの引数に何も渡しません。MVC状態変化のプロパティについて調べたいときは、呼び出し元のオブジェクトの getProperty() メソッドを使って調べます。

Map イベント

あなたはイベントの通知を受け取るために、 addListener() を使ってイベントハンドラを登録することができます。このメソッドは、オブジェクト、リッスン対象のイベント、指定されたイベントの発生時に呼び出す関数を取ります。

以下のコードは、ステート変化のイベントを使ってユーザーイベントをミックスしています。マーカーがクリックされたとき、地図のズームを変更しています。地図の'zoom' プロパティにもイベントハンドラを追加し、zoom_changed イベントを受けて、地図を オーストラリア, ノーザン・テリトリ, ダーウィン に移動します。

var map;
function initialize() {
 
var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
 
var myOptions = {
    zoom
: 4,
    center
: myLatlng,
    mapTypeId
: google.maps.MapTypeId.ROADMAP
 
}
  map
= new google.maps.Map(document.getElementById("map_canvas"), myOptions);
 
  google
.maps.event.addListener(map, 'zoom_changed', function() {
    setTimeout
(moveToDarwin, 3000);
 
});
 
 
var marker = new google.maps.Marker({
      position
: myLatlng,
      map
: map,
      title
:"Hello World!"
 
});
  google
.maps.event.addListener(marker, 'click', function() {
    map
.setZoom(8);
 
});
}
 
function moveToDarwin() {
 
var darwin = new google.maps.LatLng(-12.461334, 130.841904);
  map
.setCenter(darwin);
}

View example (event-simple.html)

注: ビューポートの変化を判定したいときは、zoom_changed とcenter_changed イベントよりも、むしろ bounds_changed イベントを指定してください。Maps API は前者のイベントとは無関係にイベントを発生させるので、getBounds() はビューポートがきちんと変化し終えるまで正しく結果を返さないかもしれません。それらイベントのあとに getBounds() イベントを使いたいときは、bounds_changed イベントを監視してください。

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

Google Maps API Version3 のUIイベントは、大体はイベントの引数を渡し、イベントリスナーを使ってアクセスすることができますが、イベントがいつ発生したかに気をつけてください。例えば、UI 'click' イベントは、通常 Mouse イベント cクリックされた地図上の位置を意味する latLng プロパティと スクリーン上のクリックされた位置を意味する pixel を渡します。
※注 : この動作は UI イベント特有のもので、MVC ステート変化のイベントでは引数は渡されないことに注意してください。

オプジェクトのプロパティにアクセスするのと同じように、イベントリスナの中であなたはイベントの引数にアクセスできます。以下の例は、地図と、地図上をクリックした位置にマーカーを作成して、そのマーカーにイベントリスナを追加しています。

var map;
function initialize() {
 
var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
 
var myOptions = {
    zoom
: 4,
    center
: myLatlng,
    mapTypeId
: google.maps.MapTypeId.ROADMAP
 
}
  map
= new google.maps.Map(document.getElementById("map_canvas"), myOptions);
 
  google
.maps.event.addListener(map, 'click', function(event) {
    placeMarker
(event.latLng);
 
});
}
 
function placeMarker(location) {
 
var clickedLocation = new google.maps.LatLng(location);
 
var marker = new google.maps.Marker({
      position
: location,
      map
: map
 
});

  map
.setCenter(location);
}

View example (event-arguments.html)

イベントリスナでクロージャを利用する

イベントリスナが実行されるとき、プライベートと持続的なデータをオブジェクトに持たせるのは、たいていの場合便利です。JavaScriptは "プライベートな" インスタンスデータを提供していませんが、クロージャ をサポートし、関数の内側から外側の変数にアクセスするのを許しています。クロージャはイベントリスナの中でイベントが発生したときにオブジェクトに含まれなかった変数にアクセスするのに役立ちます。

以下の例は、マーカーにシークレットメッセージの一部を関連付けるのに、イベントリスナの中でクロージャを使っています。各マーカーをクリックするとシークレットメッセージを見直すことができます。(秘密のメッセージは、マーカーには含まれていません)

var map;
function initialize() {
 
var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
 
var myOptions = {
    zoom
: 4,
    center
: myLatlng,
    mapTypeId
: google.maps.MapTypeId.ROADMAP
 
}

  map
= new google.maps.Map(document.getElementById("map_canvas"), myOptions);

 
// Add 5 markers to the map at random locations
 
var southWest = new google.maps.LatLng(-31.203405,125.244141);
 
var northEast = new google.maps.LatLng(-25.363882,131.044922);
 
var bounds = new google.maps.LatLngBounds(southWest,northEast);
  map
.fitBounds(bounds);
 
var lngSpan = northEast.lng() - southWest.lng();
 
var latSpan = northEast.lat() - southWest.lat();
 
for (var i = 0; i < 5; i++) {
   
var location = new google.maps.LatLng(southWest.lat() + latSpan * Math.random(),
        southWest
.lng() + lngSpan * Math.random());
   
var marker = new google.maps.Marker({
        position
: location,
        map
: map
   
});
   
var j = i + 1;
    marker
.setTitle(j.toString());
    attachSecretMessage
(marker, i);
 
}
}

// The five markers show a secret message when clicked
// but that message is not within the marker's instance data

function attachSecretMessage(marker, number) {
 
var message = ["This","is","the","secret","message"];
 
var infowindow = new google.maps.InfoWindow(
     
{ content: message[number],
        size
: new google.maps.Size(50,50)
     
});
  google
.maps.event.addListener(marker, 'click', function() {
    infowindow
.open(map,marker);
 
});
}

View example (event-closure.html)

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

イベントが発生したとき、Maps API イベントシステムの中のMVC状態変化イベントは引数を渡しません。(UIイベントは引数が渡されます。) MVC状態変化のプロパティを調べたいときは、明示的にオブジェクトの getProperty()メソッドをコールするのが良いでしょう。この方法ならイベントが最初に発生した後は、常にMVCオブジェクトの現在の状態を調べることができるでしょう。

注: explicitly setting a property within an event handler which responds to a state change of that particular property may produce unpredictable and/or unwanted behavior. Setting such a property will trigger a new event, for example, and if you always set a property within this event handler, you may end up creating an infinite loop.

In the example below, we set up an event handler to respond to zoom events by bringing up an info window displaying that level. We also check whether the map is fully zoomed-out and zoom in to zoom level 17 if so.

var map;
function initialize() {
 
var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
 
var myOptions = {
    zoom
: 4,
    center
: myLatlng,
    mapTypeId
: google.maps.MapTypeId.ROADMAP
 
}
  map
= new google.maps.Map(document.getElementById("map_canvas"), myOptions);
 
 
var zoomLevel;
 
var infowindow = new google.maps.InfoWindow(
   
{ content: 'Zoom Level Test',
        size
: new google.maps.Size(50,50),
        position
: myLatlng
   
});
  infowindow
.open(map);
   
  google
.maps.event.addListener(map, 'zoom_changed', function() {
    zoomLevel
= map.getZoom();
    infowindow
.setContent("Zoom: " + zoomLevel);
   
if (zoomLevel == 0) {
      map
.setZoom(10);
   
}      
 
});
}

View example (event-properties.html)