Skip to content

Google 地图 - 事件

Maps JavaScript API 是交互式的。用户可以点击、拖动和缩放地图,地图本身也会改变状态。您可以监听这些发生的情况,即事件,并执行自定义代码来响应。

这使您能够构建动态应用程序,例如在用户点击的位置放置标记(Marker),当地图视图更改时更新信息,或者在用户完成拖动标记时做出响应。

监听事件的标准方法是使用 addListener() 方法,该方法可用于大多数 API 对象(如 Map、Marker、Polygon、InfoWindow)。

const listener = object.addListener('event_name', (eventArguments) => {
// 事件发生时要运行的代码
// 'eventArguments' 包含特定于事件的数据(例如,点击事件的 LatLng)
});
  • object: 您想要监听的 API 对象(例如,map、marker)。
  • 'event_name': 指定要监听的事件的字符串(例如,'click'、'zoom_changed')。
  • (eventArguments) => { ... }: 事件触发时执行的处理函数(回调函数)。箭头函数通常用于简洁性和处理 this 上下文。
  • listener: addListener 方法返回一个 MapsEventListener 对象,该对象稍后可用于移除监听器。
  • click: 用户点击地图。处理程序接收包含 latLng 坐标的 MapMouseEvent。
  • dblclick: 用户双击地图。
  • rightclick: 用户右键点击地图。
  • bounds_changed: 地图的视口(viewport)边界已更改(在平移/缩放期间频繁发生)。
  • center_changed: 地图中心 LatLng 已更改。
  • zoom_changed: 地图的缩放级别已更改。
  • idle: 地图在平移或缩放后进入空闲状态(对于在移动停止后触发操作非常有用)。

常见的标记事件(Marker Events)(Marker 或 AdvancedMarkerView)

Section titled “常见的标记事件(Marker Events)(Marker 或 AdvancedMarkerView)”
  • click: 用户点击标记。
  • dblclick: 用户双击标记。
  • rightclick: 用户右键点击标记。
  • dragstart: 用户开始拖动标记(如果设置了 draggable: true)。
  • drag: 标记正在被主动拖动。
  • dragend: 用户完成拖动标记。处理程序接收包含 latLng 坐标的事件。

Polygon、Polyline 和 InfoWindow 等其他对象也具有相关的事件(例如,InfoWindow 的 click、closeclick 事件)。请查阅API 参考了解详情。

让我们添加一个监听器,用于在用户点击地图时记录坐标并在该位置放置一个简单的标记。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Map Click Event</title>
<style>#map { height: 400px; width: 100%; } html, body { height: 100%; margin: 0; padding: 0; }</style>
</head>
<body>
<div id="map"></div>
<script>
async function initMap() {
const mapCenter = { lat: 40.7128, lng: -74.0060 }; // 纽约
const { Map } = await google.maps.importLibrary("maps");
// 如果您打算在点击时放置标记,请导入 Marker 库
const { Marker } = await google.maps.importLibrary("marker");
const map = new Map(document.getElementById("map"), {
zoom: 12,
center: mapCenter,
mapId: "DEMO_MAP_ID"
});
// 为地图添加点击事件监听器
map.addListener('click', (mapsMouseEvent) => {
const clickedLatLng = mapsMouseEvent.latLng;
console.log(`Map clicked at: ${clickedLatLng.lat()}, ${clickedLatLng.lng()}`);
// 可选:在点击的位置放置一个标记
new Marker({
position: clickedLatLng,
map: map,
title: `Clicked at ${clickedLatLng.lat().toFixed(4)}, ${clickedLatLng.lng().toFixed(4)}`
});
// 可选:您可能想在这里关闭现有的 InfoWindow
});
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap&v=weekly&libraries=marker" async defer></script>
<!-- 添加了 libraries=marker -->
</body>
</html>

预期输出:一张交互式的纽约地图。点击地图上的任意位置,将会在浏览器控制台打印经度和纬度,并在该位置放置一个新的标记。

示例:在标记点击时打开 InfoWindow

Section titled “示例:在标记点击时打开 InfoWindow”

一种非常常见的模式是在用户点击标记时显示更多信息。

<!DOCTYPE html>
<!-- ... 头部 ... -->
<body>
<div id="map"></div>
<script>
let currentInfoWindow = null; // 跟踪当前打开的 InfoWindow
async function initMap() {
const mapCenter = { lat: 51.5074, lng: -0.1278 }; // 伦敦
const { Map } = await google.maps.importLibrary("maps");
const { Marker } = await google.maps.importLibrary("marker");
const { InfoWindow } = await google.maps.importLibrary("maps"); // InfoWindow 在 'maps' 库中
const map = new Map(document.getElementById("map"), {
zoom: 14,
center: mapCenter,
mapId: "DEMO_MAP_ID"
});
// 创建标记
const marker = new Marker({
position: mapCenter,
map: map,
title: 'Click for details'
});
// 创建 InfoWindow
const infowindow = new InfoWindow({
content: '<h3>Central London</h3><p>Near Trafalgar Square.</p>',
ariaLabel: 'Central London Details'
});
// 为标记添加点击事件监听器
marker.addListener('click', () => {
// 可能关闭其他 InfoWindow?(良好实践)
if (currentInfoWindow) {
currentInfoWindow.close();
}
// 打开新的 InfoWindow
infowindow.open({
anchor: marker, // 将 InfoWindow 锚定到我们的标记
map: map // 指定它所属的地图
});
currentInfoWindow = infowindow; // 跟踪当前窗口
});
// 可选:如果点击地图其他位置则关闭 InfoWindow
map.addListener('click', () => {
if (currentInfoWindow) {
currentInfoWindow.close();
currentInfoWindow = null;
}
});
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap&v=weekly&libraries=marker,maps" async defer></script>
<!-- 添加了 libraries=marker,maps -->
</body>
</html>

预期输出:一张带有标记的伦敦地图。点击标记将打开一个包含指定 HTML 内容的小弹出窗口(InfoWindow)。

处理函数通常接收包含特定事件数据的参数。最常见的是鼠标事件的 latLng 属性。

marker.addListener('dragend', (event) => {
const newPosition = event.latLng;
alert(`Marker dropped at: ${newPosition.lat()}, ${newPosition.lng()}`);
});
map.addListener('zoom_changed', () => {
const newZoom = map.getZoom();
console.log('Zoom level changed to:', newZoom);
});

请查阅特定事件的 API 参考,以了解传递给处理函数的参数。

如果您不再需要某个事件监听器(例如,为了防止内存泄漏或重复操作),应该将其移除。请在添加监听器时返回的 MapsEventListener 对象上使用 remove() 方法。

// 添加监听器并存储句柄
const mapClickListener = map.addListener('click', (event) => {
console.log('Map clicked!');
// 也许只监听第一次点击?
removeMapClickListener();
});
// 移除监听器的函数
function removeMapClickListener() {
if (mapClickListener) {
mapClickListener.remove();
console.log('Map click listener removed.');
}
}
// 示例:在 5 秒后移除监听器
// setTimeout(removeMapClickListener, 5000);

或者,较旧的静态方法 google.maps.event.removeListener(listenerObject) 仍然可用。