事件

使用集合让一切井井有条 根据您的偏好保存内容并对其进行分类。
选择平台Android iOS JavaScript

本页介绍了您可以程序化监听和处理的界面事件和错误事件。

用户界面事件

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

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

每个 Maps JavaScript API 对象都会导出大量已命名的事件。对某些事件感兴趣的程序会为这些事件注册 JavaScript 事件监听器,并在收到这些事件后执行代码,方法是调用 addListener() 在对象上注册事件处理程序。

以下示例显示了您与地图互动时 google.maps.Map 触发了哪些事件。

如需查看完整的事件列表,请参阅 Maps JavaScript API 参考文档。 系统会针对每个包含事件的对象在单独的部分中列出事件。

界面事件

Maps JavaScript API 中的一些对象旨在响应鼠标事件或键盘事件等用户事件。例如,下面是 google.maps.Marker 对象可以监听的一些用户事件:

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

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

MVC 状态更改

MVC对象通常都有相应的状态。每当对象的属性发生变化时,Maps JavaScript API 都会触发该属性已更改的事件。 例如,该 API 会在地图的缩放级别发生变化时触发地图上的 zoom_changed 事件。您也可以通过调用 addListener() 在对象上注册事件处理程序来拦截这些状态更改。

用户事件和 MVC 状态更改可能看起来相似,但您通常希望在代码中对它们进行不同的处理。例如,MVC 事件不会在其事件中传递参数。您需要对该对象调用相应的 getProperty 方法,检查在 MVC 状态更改时更改的属性。

处理事件

如需注册事件通知,请使用 addListener() 事件处理脚本。该方法接受要监听的事件以及要在指定事件发生时调用的函数。

示例:地图和标记事件

以下代码将用户事件与状态更改事件混合在一起。我们向标记附加了事件处理脚本,该标记可在用户点击时缩放地图。我们还针对 center 属性的更改向地图添加了事件处理脚本,并在收到 center_changed 事件 3 秒后将地图平移回标记处:

TypeScript

function initMap(): void {
  const myLatlng = { lat: -25.363, lng: 131.044 };

  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 4,
      center: myLatlng,
    }
  );

  const marker = new google.maps.Marker({
    position: myLatlng,
    map,
    title: "Click to zoom",
  });

  map.addListener("center_changed", () => {
    // 3 seconds after the center of the map has changed, pan back to the
    // marker.
    window.setTimeout(() => {
      map.panTo(marker.getPosition() as google.maps.LatLng);
    }, 3000);
  });

  marker.addListener("click", () => {
    map.setZoom(8);
    map.setCenter(marker.getPosition() as google.maps.LatLng);
  });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const myLatlng = { lat: -25.363, lng: 131.044 };
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: myLatlng,
  });
  const marker = new google.maps.Marker({
    position: myLatlng,
    map,
    title: "Click to zoom",
  });

  map.addListener("center_changed", () => {
    // 3 seconds after the center of the map has changed, pan back to the
    // marker.
    window.setTimeout(() => {
      map.panTo(marker.getPosition());
    }, 3000);
  });
  marker.addListener("click", () => {
    map.setZoom(8);
    map.setCenter(marker.getPosition());
  });
}

window.initMap = initMap;
查看示例

试用示例

提示:如果您正在尝试检测视口中的变化,请务必使用特定的 bounds_changed 事件,而不是组成部分 zoom_changedcenter_changed 事件。由于 Maps JavaScript API 会单独触发后面的两个事件,因此,只有在系统强制更改了视口后,getBounds() 才会报告实用结果。如果您希望在此类事件之后使用 getBounds(),请务必改为监听 bounds_changed 事件。

示例:形状修改和拖动事件

修改或拖动形状时,系统会在操作完成时触发事件。如需查看事件和一些代码段的列表,请参阅形状

查看示例 (rectangle-event.html)

访问 UI 事件中的自变量

Maps JavaScript API 中的界面事件通常会传递事件参数,您可通过事件监听器访问这些参数,其中会注明事件发生时的界面状态。例如,界面 'click' 事件通常会传递一个包含 latLng 属性的 MouseEvent,该属性表示地图上的点击位置。请注意,此行为是界面事件所独有的;MVC 状态更改不会在其事件中传递参数。

您可以像访问对象的属性一样访问事件监听器中的事件参数。以下示例展示了如何为地图添加事件监听器,并在用户点击所点击地点的地图时创建标记。

TypeScript

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 4,
      center: { lat: -25.363882, lng: 131.044922 },
    }
  );

  map.addListener("click", (e) => {
    placeMarkerAndPanTo(e.latLng, map);
  });
}

function placeMarkerAndPanTo(latLng: google.maps.LatLng, map: google.maps.Map) {
  new google.maps.Marker({
    position: latLng,
    map: map,
  });
  map.panTo(latLng);
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: { lat: -25.363882, lng: 131.044922 },
  });

  map.addListener("click", (e) => {
    placeMarkerAndPanTo(e.latLng, map);
  });
}

function placeMarkerAndPanTo(latLng, map) {
  new google.maps.Marker({
    position: latLng,
    map: map,
  });
  map.panTo(latLng);
}

window.initMap = initMap;
查看示例

试用示例

在事件侦听器中使用闭包

执行事件监听器时,通常建议您同时将私有数据和持久性数据附加到对象上。JavaScript 不支持“私有”实例数据,但支持闭包(允许内部函数访问外部变量)。关闭事件对于在事件监听器中访问通常不会附加到发生事件的对象的变量非常有用。

以下示例在事件监听器中使用了函数闭包将加密消息分配给一组标记。点击每个标记可显示一部分保密消息,该标记未包含在标记本身中。

TypeScript

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 4,
      center: { lat: -25.363882, lng: 131.044922 },
    }
  );

  const bounds: google.maps.LatLngBoundsLiteral = {
    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.
  const secretMessages = ["This", "is", "the", "secret", "message"];
  const lngSpan = bounds.east - bounds.west;
  const latSpan = bounds.north - bounds.south;

  for (let i = 0; i < secretMessages.length; ++i) {
    const 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: google.maps.Marker,
  secretMessage: string
) {
  const infowindow = new google.maps.InfoWindow({
    content: secretMessage,
  });

  marker.addListener("click", () => {
    infowindow.open(marker.get("map"), marker);
  });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: { lat: -25.363882, lng: 131.044922 },
  });
  const 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.
  const secretMessages = ["This", "is", "the", "secret", "message"];
  const lngSpan = bounds.east - bounds.west;
  const latSpan = bounds.north - bounds.south;

  for (let i = 0; i < secretMessages.length; ++i) {
    const 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) {
  const infowindow = new google.maps.InfoWindow({
    content: secretMessage,
  });

  marker.addListener("click", () => {
    infowindow.open(marker.get("map"), marker);
  });
}

window.initMap = initMap;
查看示例

试用示例

获取和设置事件处理脚本中的属性

Maps JavaScript API 事件系统中没有任何 MVC 状态更改事件在事件触发时传递参数。(用户事件确实会传递可以检查的参数。)如果您需要检查有关 MVC 状态更改的属性,则应针对该对象明确调用相应的 getProperty() 方法。此检查将始终检索 MVC 对象的当前状态,而这可能不是事件首次触发时的状态。

注意:在对特定属性的状态变化做出响应的事件处理程序中,明确设置某个属性可能会产生不可预期和/或不必要的行为。例如,设置此类属性会触发新事件,而且,如果您总是在此事件处理脚本中设置属性,那么最终可能会造成无限循环。

在以下示例中,我们设置了一个事件处理脚本,通过调出显示该级别的信息窗口来响应缩放事件。

TypeScript

function initMap(): void {
  const originalMapCenter = new google.maps.LatLng(-25.363882, 131.044922);
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 4,
      center: originalMapCenter,
    }
  );

  const infowindow = new google.maps.InfoWindow({
    content: "Change the zoom level",
    position: originalMapCenter,
  });

  infowindow.open(map);

  map.addListener("zoom_changed", () => {
    infowindow.setContent("Zoom: " + map.getZoom()!);
  });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const originalMapCenter = new google.maps.LatLng(-25.363882, 131.044922);
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: originalMapCenter,
  });
  const infowindow = new google.maps.InfoWindow({
    content: "Change the zoom level",
    position: originalMapCenter,
  });

  infowindow.open(map);
  map.addListener("zoom_changed", () => {
    infowindow.setContent("Zoom: " + map.getZoom());
  });
}

window.initMap = initMap;
查看示例

试用示例

侦听 DOM 事件

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 级别参考文档。)

TypeScript

function initMap(): void {
  const mapDiv = document.getElementById("map") as HTMLElement;
  const map = new google.maps.Map(mapDiv, {
    zoom: 8,
    center: new google.maps.LatLng(-34.397, 150.644),
  });

  // We add a DOM event here to show an alert if the DIV containing the
  // map is clicked.
  google.maps.event.addDomListener(mapDiv, "click", () => {
    window.alert("Map was clicked!");
  });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const mapDiv = document.getElementById("map");
  const map = new google.maps.Map(mapDiv, {
    zoom: 8,
    center: new google.maps.LatLng(-34.397, 150.644),
  });

  // We add a DOM event here to show an alert if the DIV containing the
  // map is clicked.
  google.maps.event.addDomListener(mapDiv, "click", () => {
    window.alert("Map was clicked!");
  });
}

window.initMap = initMap;

HTML

<html>
  <head>
    <title>Listening to DOM Events</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="map"></div>

    <!-- 
     The `defer` attribute causes the callback to execute after the full HTML
     document has been parsed. For non-blocking uses, avoiding race conditions,
     and consistent behavior across browsers, consider loading using Promises
     with https://www.npmjs.com/package/@googlemaps/js-api-loader.
    -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
      defer
    ></script>
  </body>
</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 命名空间的参考文档。

侦听身份验证错误

如果要以编程方式检测身份验证失败的情况(例如,自动发送信标),您可以准备回调函数。 如果定义了以下全局函数,则系统会在身份验证失败时调用该函数。 function gm_authFailure() { /* Code */ };