My favorites | 中文(繁體) | Sign in
英文版或許有比此中譯版新的內容

Google 地圖 API 專業版

同樣好用的地圖,再加上 SLA、支援以及廣告的控制

事件

地圖事件總覽

瀏覽器中的 JavaScript 為「事件驅動」,會因應互動事件而再產生事件,並預期程式會「接聽」相關的事件。例如在瀏覽器中,使用者滑鼠和鍵盤的互動就會建立 DOM 中的事件。與特定事件相關的程式,會為那些事件註冊 JavaScript 事件接聽程式,並於接收到那些事件時執行程式碼。

藉由定義「地圖 API」物件的自訂事件,「Google 地圖 API」新增此事件模型。需要注意的是,「地圖 API」事件與標準的 DOM 事件是獨立且不同的。然而,因為不同瀏覽器實作不同的 DOM 事件模型,因此「地圖 API」也提供機制,來接聽或回應這些 DOM 事件,而不需要處理各種跨瀏覽器的細節。

事件接聽程式

「Google 地圖 API」中的事件,是使用 GEvent 命名空間中公用程式函式註冊事件接聽程式的方式進行處理。每個「地圖 API」物件匯出一系列具名的事件。例如,GMap2 物件匯出 clickdblclickmove 事件,其他物件也會產生類似事件。每個事件會在指定情境中發生,而且可以傳送識別該情境的引數。例如,如果使用者在地圖物件中移動滑鼠,並傳送滑鼠所在之地理位置的 GLatLng,就會引發 mousemove 事件。

如需 GMap2 事件及其產生引數的完整清單,請參閱 GMap2.Events

若要註冊這些事件的通知,請使用靜態方法 GEvent.addListener()。該方法可接受物件、要接聽的事件以及特定事件發生時要呼叫的函式。例如,每當使用者在地圖上按一下,此程式碼片段就會顯示警示:

var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
GEvent.addListener(map, "click", function() {
  alert("You clicked the map.");
});

檢視範例 (event-simple.html)

接聽程式也可以擷取事件的情境。下列範例程式碼中,我們顯示使用者拖曳地圖後該地圖中心的經緯度。

var map = new GMap2(document.getElementById("map"));
GEvent.addListener(map, "moveend", function() {
  var center = map.getCenter();
  document.getElementById("message").innerHTML = center.toString();
});
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

檢視範例 (event-context.html)

在事件接聽程式中使用 Closure

執行事件接聽程式時,物件最好同時具有私有和持續性資料。JavaScript 不支援「private」實例資料,但是支援 closure (可允許內部函式存取外部變數)。Closure 在事件接聽程式中很有用,可存取一般通常不會附加至事件發生時物件上的變數。

下列範例在事件接聽程式中使用函式 Closure,以指派秘密訊息給標記集。按一下每個標記可檢視秘密訊息的一部分,標記本身不含秘密訊息。

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

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

function createMarker(point, number) {
  var marker = new GMarker(point);
  var message = ["This","is","the","secret","message"];
  marker.value = number;
  GEvent.addListener(marker, "click", function() {
    var myHtml = "<b>#" + number + "</b><br/>" + message[number -1];
    map.openInfoWindowHtml(point, myHtml);
  });
  return marker;
}

// Add 5 markers to the map at random locations
var bounds = map.getBounds();
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 < 5; i++) {
  var point = new GLatLng(southWest.lat() + latSpan * Math.random(),
    southWest.lng() + lngSpan * Math.random());
  map.addOverlay(createMarker(point, i + 1));
}

檢視範例 (event-closure.html)

在事件中使用傳送的引數

「地圖 API」事件系統中的很多事件,在事件觸發時,都會傳送引數。如果在地圖的疊加層發生點擊的話,則 GMap2「按一下」事件會傳送 overlayoverlaylatlng;否則它會傳送地圖座標的 latlng。您可以將指定的符號直接傳送給事件接聽程式中的函式,以使用這些引數。

在下列範例中,我們先進行測試,以確認「按一下」是位於地圖方塊上 (檢查是否已定義 latlng 引數);如果是的話,我們會在按一下的座標上方開啟資訊視窗,顯示轉換為像素空間與縮放等級的座標。

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

GEvent.addListener(map,"click", function(overlay, latlng) {     
  if (latlng) { 
    var myHtml = "The GPoint value is: " + map.fromLatLngToDivPixel(latlng) + " at zoom level " + map.getZoom();
    map.openInfoWindow(latlng, myHtml);
  }
});
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());

檢視範例 (event-arguments.html)

將事件繫結至物件方法

如果想要將事件接聽程式附加至物件的特定實例,函式就非常好用。如果相反地,您是希望有方法可以叫用回應事件之物件的所有實例,則可以使用 GEvent.bind()。在下列範例中,應用程式類別實例將地圖事件繫結至其本身的方法中,當事件觸發時會修改類別狀態:

function MyApplication() {
  this.counter = 0;
  this.map = new GMap2(document.getElementById("map"));
  this.map.setCenter(new GLatLng(37.4419, -122.1419), 13);
  GEvent.bind(this.map, "click", this, this.onMapClick);
}

MyApplication.prototype.onMapClick = function() {
  this.counter++;
  alert("You have clicked the map " + this.counter + " " +
        (this.counter == 1 ? "time" : "times"));
}

var application = new MyApplication();

檢視範例 (event-bind.html)

接聽 DOM 事件

「Google 地圖 API」事件模型建立並管理其本身的自訂事件。不過,DOM 也會根據使用中的特殊瀏覽器事件模型,來建立並分派其自己的事件。如果您想要擷取並回應這些事件,「Google 地圖 API」提供適用各種瀏覽器的包裝函式,來接聽和繫結 DOM 事件,而不需要自訂程式碼。

GEvent.addDomListener() 靜態方法會在 DOM 節點為 DOM 事件註冊事件處理常式。同樣地,靜態方法 GEvent.bindDom() 允許您為類別實例上的 DOM 事件註冊事件處理常式。

移除事件接聽程式

不再需要事件接聽程式時,應將它移除。如果事件只需要引發一次,就可能需要用到。要移除在 Closure 中透過匿名函式定義的事件接聽程式,可能有點困難。不過,addListener()addDomListener()bind() 以及 bindDom() 函式會傳回 GEventListener 控制代碼,可於稍後解除註冊處理常式。

下列範例會在地圖上放置標記,以回應按一下的動作。任何後續的點擊都會移除該事件接聽程式。請注意,removeOverlay() 程式碼不會作為結果執行。同時,也請注意,您甚至可以在事件接聽程式本身之中移除事件接聽程式。

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

function load() {
  var application = new MyApplication();
}

檢視範例 (event-removal.html)