英文 | 站点目录

事件

地图事件概述

浏览器中的 JavaScript 是事件驱动的,意味着 JavaScript 通过生成事件来响应交互,并用程序来侦听有趣的事件。例如,在浏览器中,用户鼠标和键盘交互会创建在 DOM 内传播的事件。对某些事件感兴趣的程序将为这些事件注册 JavaScript 事件侦听器,并在收到这些事件时执行代码。

Google 地图 API 通过为地图 API 对象定义定制事件而成为这种事件模型的一部分。要注意 地图 API 事件与标准 DOM 事件不同。另外,由于不同的浏览器支持不同的 DOM 事件模型, 地图 API 还提供侦听和响应这些 DOM 事件而无需处理各种跨浏览器特性的机制。

事件侦听器

处理 Google 地图 API 中的事件的方式是使用 GEvent 名称空间中的工具函数注册事件侦听器。每个 地图 API 对象都导出了多个命名事件。例如,GMap2 对象导出 clickdblclickmove 事件,以及许多其他事件。每个事件都在给定环境下发生,并且可以传递标识该环境的参数。例如,当用户在地图对象中移动鼠标时,会触发 mousemove 事件,并传递鼠标所在地理位置的 GLatLng

关于GMap2 事件和以及相关参数的完整列表,请参阅 GMap2.Events

要注册以获取这些事件相关的通知,请使用静态方法 GEvent.addListener()。该方法的参数为待侦听对象、待侦听事件以及回调函数。例如,在以下代码片段中,每次用户单击地图都会时出现警告。

var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(39.917,116.397), 14);
GEvent.addListener(map, "click", function() {
  alert("您点击了地图。");
});

查看示例 (event-simple.html)

侦听器也能够捕获事件的环境。 在以下示例代码中,我们显示用户缩放地图后地图的缩放级别。

var map = new GMap2(document.getElementById("map"));
map.setCenter(new GlatLng(39.917,116.397), 14);
GEvent.addListener(map, "zoomend", function() {
  var center = map.getCenter();
  document.getElementById("message").innerHTML =
      "缩放级别为:" + map.getZoom();
});

查看示例 (event-context.html)

在事件侦听器中使用 closures

当执行事件侦听器时,通常较好的做法是同时将私有数据和持久数据与一个对象关联。JavaScript 不支持“私有”实例数据,但它支持允许内部函数访问外部变量的 closures。在事件侦听器中要访问通常与事件发生相关对象不关联的变量时,closures 非常有用。

以下示例在事件侦听器中使用 closures 将一个秘密消息分配给一组标记(Marker)。单击任何标记将可以查看秘密消息的一部分,秘密消息并不包含在标记本身内。

var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new Glatlng(39.917,116.397), 14);

// 在给定点创建标记
// 五个标记在单击时显示秘密消息,但该消息不在标记的实例数据中

function createMarker(point, number) {
  var marker = new GMarker(point);
  var message = ["这","是","个","秘密","消息"];
  marker.value = number;
  GEvent.addListener(marker, "click", function() {
    var myHtml = "<b>#" + number + "</b><br/>" + message[number -1];
    map.openInfoWindowHtml(point, myHtml);
  });
  return marker;
}

// 在地图的随机位置添加 5 个标记
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 "click" 事件可以传递两个参数 (overlay,point)。可以通过将指定的符号直接传递给事件侦听器中的函数而访问这些参数。

例如,地图上的 "click" 事件可以传递 overlaypoint 参数。我们在回调函数内直接传递这些参数以在事件侦听器内调用。

var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(39.917,116.397), 14);

GEvent.addListener(map,"click", function(overlay,point) {
  var myHtml = "GPoint 为:" + map.fromLatLngToDivPixel(point) + ",缩放级别为:" + map.getZoom();
  map.openInfoWindow(point, myHtml);
});
map.addControl(new GSmallMapControl());

查看示例 (event-arguments.html)

将事件绑定到对象方法

当要将事件侦听器与对象的特定实例相关联时,函数非常有用。 相反,如果你希望在响应事件时对象的所有实例都调用某方法,可以使用 GEvent.bind()。在以下示例中,一个应用程序类实例将地图事件与其自身的方法绑定在一起,修改了触发事件时的类状态:

function MyApplication() {
  this.counter = 0;
  this.map = new GMap2(document.getElementById("map"));
  this.map.setCenter(new GLatLng(39.917,116.397), 14);
  GEvent.bind(this.map, "click", this, this.onMapClick);
}

MyApplication.prototype.onMapClick = function() {
  this.counter++;
  alert("这是您第 " + this.counter + " 次点击地图"); 
}

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() 句柄,它可以用于最终取消注册处理程序。

以下实例响应单击,在地图上添加标注。之后的任何单击将会删除该事件侦听器。请注意结果将不再执行 removeOverlay() 代码。同时,请注意甚至可以从事件侦听器本身的内部删除事件侦听器。

function MyApplication() {
  this.counter = 0;
  this.map = new GMap2(document.getElementById("map"));
  this.map.setCenter(new GLatLng(39.917,116.397), 14);
  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);
    }
  }); 
}

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

查看示例 (event-removal.html)