お気に入り | 日本語 | ログイン

マプレット イベント

  1. イベントの概要
    1. イベントリスナ
    2. イベント クロージャ
    3. イベント引数
    4. DOM イベント
    5. イベントリスナを削除する

マプレット イベントの概要

ブラウザ内の JavaScript は「イベント駆動型」です。つまり、JavaScript はイベントを生成することで操作に応答し、プログラムは目的のイベントを「リッスン」します。たとえばブラウザ内では、ユーザーのマウスとキーボードの操作によって、DOM 内に反映されるイベントが生成されます。特定のイベントを監視しているプログラムは、それらのイベントの JavaScript イベントリスナを登録して、これらのイベントが受信されたときにコードを実行します。

Google Mapplets API は、マプレット オブジェクトのカスタム イベントを定義することで、このイベント モデルを増強します。Mapplets API イベントは、標準の DOM イベントとは異なる別のイベントである点にご注意ください。ただし、ブラウザごとに異なる DOM イベント モデルが実装されるため、Mapplets API は、さまざまなブラウザ固有の性質に対処しなくても、これらの DOM イベントをリッスンしたり応答したりできる機能を備えています。

イベントリスナ

Mapplets API 内のイベントは、GEvent 名前空間内のユーティリティ関数を使用してイベント リスナを登録することで処理されます。各 Mapplets API オブジェクトは、いくつかの名前付きイベントをエクスポートします。たとえば GMap2 オブジェクトは、clickdblclickmove イベントを含む多数のイベントをエクスポートします。各イベントは特定のコンテキスト内で発生して、そのコンテキストを識別する引数を渡すことができます。たとえば dragstart イベントは、ユーザーがマップ オブジェクト内でマウスをクリックしたままにしたときに発生して、マウスが配置されている地理的位置の GLatLng を渡します。

GMap2 イベントとこれらが生成する引数の全リストについては、GMap2.Events を参照してください。

これらのイベントの通知に登録するには、静的メソッド GEvent.addListener() を使用してください。このメソッドは、オブジェクト、リッスン対象のイベント、指定されたイベントの発生時に呼び出す関数を取ります。たとえば次のコード スニペットは、ユーザーが地図上でクリックするたびにアラートを表示します。

var map = new GMap2();

GEvent.addListener(map, "click", function(marker, point) {
  if (marker) {
    map.removeOverlay(marker);
  } else {
    map.addOverlay(new GMarker(point));
  }
});

この例を実行する (event-simple.xml)

リスナは、イベントのコンテキストを取得することもできます。次のサンプル コードでは、ユーザーが地図をドラッグした後の、地図の中心の緯度と経度を表示します。

var map = new GMap2();
GEvent.addListener(map, "moveend", function() {
  map.getCenterAsync(function(center) {
    map.openInfoWindowHtml(center, center.toString());
  });
});
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

この例を実行する (event-context.xml)

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

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

次の例では、イベント リスナ内で関数クロージャを使用して、一連のマーカーにシーケンス番号値を割り当てています。各マーカーをクリックすると、そのマーカー自体には含まれていない個別の値が表示されます。

var map = new GMap2();

// Creates a marker at the given point with the given number label
function createMarker(point, number) {
  var marker = new GMarker(point);
  GEvent.addListener(marker, "click", function() {
    marker.openInfoWindowHtml("Marker #" + number);
  });
  return marker;
}

// Add 10 markers to the map at random locations
map.getBoundsAsync(function(bounds) {
  var southWest = bounds.getSouthWest();
  var northEast = bounds.getNorthEast();
  var lngSpan = northEast.lng() - southWest.lng();
  var latSpan = northEast.lat() - southWest.lat();

  for (var i = 0; i < 10; i++) {
    var point = new GLatLng(southWest.lat() + latSpan * Math.random(),
                            southWest.lng() + lngSpan * Math.random());
    map.addOverlay(createMarker(point, i + 1));
  }
});

この例を実行する (event-closure.xml)

渡された引数をイベントで使用する

Mapplets API イベントシステム内の多くのイベントは、そのイベントがトリガされたときに引数を渡します。たとえば GMap2 「クリック」イベントは、2 つの引数(overlay,point)をイベント内で渡します。これらの引数にアクセスするには、指定された記号をイベントリスナ内の関数に直接渡します。

たとえば、地図上の "click" イベントは、overlay point という引数を渡します。これらの引数は、イベントリスナ内で呼び出すコールバック関数内で直接渡します。

この例では、2 つの非同期要求を発行して、ピクセル座標と現在のズーム レベルを取得する必要があります。GAsync() を使用してこれらのリクエストを並行処理してから、これらの戻り値に基づいてコールバック メソッドを開始します。

  var map = new GMap2();
  map.setCenter(new GLatLng(37.4419, -122.1419), 13);

  GEvent.addListener(map,"click", function(overlay,point) {
    if (point) {
      GAsync(map, 'fromLatLngToDivPixel', [point], 'getZoom', function(divPixel, zoom) {
        var myHtml = "The GPoint value is: " + divPixel + " at zoom level " + zoom;
        map.openInfoWindow(point, myHtml);
      });
    }
  });

この例を実行する (event-arguments.xml)

DOM イベントをリッスンする

Mapplets API イベント モデルは、独自のカスタム イベントを作成して管理します。ただし DOM も、使用されている特定のブラウザ イベント モデルに従って独自のイベントを作成して送出します。これらのイベントを取得して応答する必要がある場合は、Mapplets API が提供するブラウザに依存しないラッパーを使用することで、カスタム コードを使用せずに DOM イベントをリッスンしてバインドできます。マプレットは、自身の <iframe> 内の DOM イベントのみをリッスンできます。

GEvent.addDomListener() 静的メソッドは、DOM ノード上の DOM イベントのイベント ハンドラを登録します。同様に GEvent.bindDom() 静的メソッドを使用すると、クラスインスタンス上の DOM イベントのイベント ハンドラを登録できます。

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

不要になったイベントリスナは削除する必要があります。リスナが残っていると通信負荷が増大するため、このことはマプレットでは特に重要です。クロージャ内の名前のない関数を介して定義されたイベントリスナは、削除するのが難しい場合があります。ただし、addListener()addDomListener()bind()bindDom() の各関数は、最終的にハンドラの登録を解除するために使用できる GEventListener ハンドルを返します。

次の例では、クリックに応じて地図上にマーカーを配置します。その後で再びクリックされるとイベントリスナが削除されます。removeOverlay() コードは結果として一度も実行されない点に注目してください。また、イベントリスナ自体からもそのイベントリスナを削除できる点にも注目してください。

function MyApplication() {
  this.counter = 0;
  this.map = new GMap2();
  this.map.setCenter(new GLatLng(37.4419, -122.1419), 13);
  var myEventListener = GEvent.bind(this.map, "click", this, function(marker,point) {
    if (this.counter == 0) {
      if (point) {
        this.map.addOverlay(new GMarker(point))
        this.counter++;
      } else {
        this.removeOverlay(marker)
      }
    } else {
      GEvent.removeListener(myEventListener);
    }
  }); 
}
var application = new MyApplication();

この例を実行する (event-removal.xml)

マプレット オーバーレイに続きます。