一切就绪!

着手开发前,请先阅读我们的开发者文档

激活 Google Maps JavaScript API

为帮助您起步,我们将引导您在 Google Developers Console 中先完成几项任务:

  1. 创建或选择项目
  2. 激活 Google Maps JavaScript API 及相关服务
  3. 创建相应密钥
继续

事件

本页面介绍可通过编程方式侦听和处理的用户界面事件和错误事件。

用户界面事件

浏览器中的 JavaScript 是由事件驱动的,这表示 JavaScript 会通过生成事件来响应交互,并期望程序侦听感兴趣的事件。事件分为两种类型:

  • 用户事件(如“点击”鼠标事件)从 DOM 传播到 Google Maps JavaScript API。这些事件是独立的,并且与标准 DOM 事件不同。
  • MVC 状态更改通知反映了 Maps JavaScript API 对象中的变化,并会根据 property_changed 惯例命名。

每个 Maps JavaScript API 对象都会导出大量已命名的事件。如果程序想要实现某些事件,则会为这些事件注册 JavaScript 事件侦听器,并调用 addListener() 在对象上注册事件处理程序,以便在收到这些事件时执行相应代码。

下例将向您介绍当您与地图交互时 google.maps.Map 会触发哪些事件。

有关完整的事件列表,请查阅 Google Maps JavaScript API 参考资料。对于包含事件的各个对象,我们在单独的部分中列出了这些对象的事件。

用户界面事件

Google Maps JavaScript API 中的一些对象旨在对用户事件(例如鼠标事件或键盘事件)作出响应。google.maps.Marker 对象可以侦听一些用户事件,例如:

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

有关完整列表,请参阅 Marker 类。这些事件可能看上去像是标准 DOM 事件,但实际上却是 Maps JavaScript API 的一部分。由于不同的浏览器所实现的 DOM 事件模型并不相同,因此,Maps JavaScript API 提供了这些机制来侦听和响应 DOM 事件,而无需处理各种跨浏览器特性。这些事件通常还会在表明某些用户界面状态(例如鼠标位置)的事件中传递自变量。

MVC 状态更改

MVC 对象通常都包含状态。只要更改了对象的属性,Google Maps JavaScript API 就会触发已更改该属性的事件。例如,当地图的缩放级别更改后,API 将会触发地图上的 zoom_changed 事件。您也可以通过调用 addListener() 在对象上注册事件处理程序来拦截这些状态更改。

用户事件和 MVC 状态更改看上去很相似,但通常情况下,您会希望在代码中对它们进行不同的处理。例如,MVC 事件不在其事件中传递自变量。您可能需要调用该对象上的相应 getProperty 方法,以检查 MVC 状态更改中所更改的属性。

处理事件

您可以使用 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());
  });
}
<div id="map"></div>
/* Always set the map height explicitly to define the size of the div
 * element that contains the map. */
#map {
  height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
 <!-- Replace the value of the key parameter with your own API key. -->
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap">
</script>
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 JavaScript API 会单独触发后面的两个事件,因此,只有在系统强制更改了视口后,getBounds() 才会报告实用结果。如果您想要在此类事件之后获得 getBounds(),请务必改为侦听 bounds_changed 事件。

示例:形状编辑和拖动事件

编辑或拖动形状时,系统会在操作完成后立即触发相应的事件。有关事件列表及一些代码段,请参阅形状

查看示例 (rectangle-event.html)

访问用户界面事件中的自变量

通常情况下,Google Maps JavaScript API 中的 UI 事件会传递事件自变量,您可通过事件侦听器访问该自变量(其中注明了事件发生时的 UI 状态)。例如,用户界面 'click' 事件通常会传递一个包含 latLng 属性的 MouseEvent,该属性指示了地图上的点击位置。请注意,这是用户界面事件所独有的行为;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);
}
<div id="map"></div>
/* Always set the map height explicitly to define the size of the div
 * element that contains the map. */
#map {
  height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
 <!-- Replace the value of the key parameter with your own API key. -->
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap">
</script>
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);
  });
}
<div id="map"></div>
/* Always set the map height explicitly to define the size of the div
 * element that contains the map. */
#map {
  height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
 <!-- Replace the value of the key parameter with your own API key. -->
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap">
</script>
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)

获取和设置事件处理程序中的属性

Google Maps JavaScript API 事件系统中没有任何 MVC 状态更改事件会在事件触发时传递自变量。(用户事件确实会传递自变量,这是可以检查到的。)如果您需要检查有关 MVC 状态更改的属性,则应对该对象显式调用相应的 getProperty() 方法。在此检查过程中,系统会始终检索 MVC 对象的当前状态,不过该状态可能不是 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());
  });
}
<div id="map"></div>
/* Always set the map height explicitly to define the size of the div
 * element that contains the map. */
#map {
  height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
 <!-- Replace the value of the key parameter with your own API key. -->
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap">
</script>
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 JavaScript API 提供的 addDomListener() 静态方法来侦听并绑定到这些 DOM 事件。

该方法易于使用,且具有如下所示的签名:

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

其中 instance 可能是浏览器支持的任意 DOM 元素,包括:

  • DOM 的分层组成部分,例如 windowdocument.body.myform
  • 已命名的元素,例如 document.getElementById("foo")

请注意,addDomListener() 只是将指明的事件传递给浏览器,以便系统根据浏览器的 DOM 事件模型来处理该事件;不过,几乎所有的热门浏览器都至少支持 DOM 级别 2。(有关 DOM 级别事件的详细信息,请参阅 Mozilla DOM 级别参考。)

看到这里,您可能已经熟悉了 window.onload 这一 DOM 事件,我们已在 <body> 标记中对该事件进行了处理。我们在 HTML 网页完全加载后,使用该事件触发了初始 JavaScript 代码,如下所示:

<script>
  function initialize() {

    // Map initialization

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

尽管此处将该事件附加到了 <body> 元素,但该事件实际上为 window 事件,表明 window 元素下的 DOM 分层已经全部构建并呈现完毕。

onload 事件放置在 <body> 标记内虽然易于理解,但会将内容与行为混淆起来。一般而言,最佳做法是将内容代码 (HTML) 与行为代码 (JavaScript) 分隔开来,并单独提供显示代码 (CSS)。要实现此目的,您可以将自己的 Maps JavaScript API 代码中的内嵌 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 与其常规网域之外的对象进行通信。

删除事件侦听器

要删除某特定事件侦听器,必须已经将其分配给一个变量。然后,您可以调用 removeListener() 并向其传递侦听器被分配到的变量名称。

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

google.maps.event.removeListener(listener1);

要从一个特定实例中删除所有侦听器,请调用 clearInstanceListeners() 并向其传递实例名称。

var listener1 = marker.addListener('click', aFunction);
var listener2 = marker.addListener('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 namespace 的参考文档。

侦听身份验证错误

如果您想通过编程方式检测身份验证故障(例如,自动发送信标),可以准备一个回调函数。如果定义了以下全局函数,系统将在身份验证失败时调用它。function gm_authFailure() { /* Code */ };

发送以下问题的反馈:

此网页
Google Maps JavaScript API
Google Maps JavaScript API
需要帮助?请访问我们的支持页面