如何知道哪个标记被谷歌地图点击了

How to know which marker was clicked GoogleMaps

本文关键字:谷歌地图 何知道      更新时间:2023-09-26

我正在用Google Maps JavaScript API v3做一个使用JavaScript、CSS和HTML的小型HTML5项目。

在这个小应用程序中,我的目标是将标记添加到地图中,单击每个标记后,显示有关标记的一些信息。

我的第一个方法是:

var markersArray = [];
// Adds a marker to the map and push to the array.
function addMarker(location) {
    var marker = new google.maps.Marker({
        position: location,
        map: map,
        draggable: true,
        animation: google.maps.Animation.DROP,
        label: markersArray.length + "",
        title: markersArray.length + ""
    });
    markersArray.push(marker);
    marker.addListener('click', function() {
        clickMarkerEvent(markersArray.length - 1);
    });
}
//listener
function clickMarkerEvent(index) {
    alert(markersArray[index].getTitle());
}

但是,当我单击标记时,我只会得到关于放置在地图上的最后一个标记的信息。侦听器失败。

我试图通过在JavaScript中使用作用域来纠正这一问题,我甚至研究了绑定,但这些都不起作用。

最后,我想出了一个完全不同的东西:

var markersArray = [];
var lastMarkerClicked;    
function addMarker(location) {
    var marker = new google.maps.Marker({
        position: location,
        map: map,
        draggable: true,
        animation: google.maps.Animation.DROP,
        label: markersArray.length + "",
        title: markersArray.length + ""
    });
    markersArray.push(marker);
    marker.addListener('click', function() {
        clickMarkerEvent();
    });
}
//listener
function clickMarkerEvent() {
    lastMarkerClicked = event.target || event.srcElement;
    alert(markersArray[lastMarkerClicked].title);
}

最后一种方法(即使有效)的问题如下:

  • 我正在访问HTML元素,而不是JavaScript元素本身
  • 我被迫使用HTML的title属性来跟踪索引,这只能在Marker的标题是索引的情况下完成(不能是其他任何内容)
  • 我不能使用这里描述的方法(https://developers.google.com/android/reference/com/google/android/gms/maps/model/Marker#public-方法摘要),除非我做类似markersArray[lastMarkerClicked.title]的事情,它指回最后一点

总的来说,我的解决方案是有效的,但我真的不喜欢它。有更好的方法吗?

以下是我的代码,我愿意接受建议!

'use strict'
/*
	Best practices: For the best user experience, only one info window should be 
	open on the map at any one time. Multiple info windows make the map appear 
	cluttered. If you only need one info window at a time, you can create just 
	one InfoWindow object and open it at different locations or markers upon map
	events, such as user clicks. If you do need more than one info window, you 
	can display multiple InfoWindow objects at the same time.
*/
var infowindow;
var contentString;
var lastMarkerClicked;
var markersArray = [];
var map;
//	Initializes the map with a marker
function initMap() {
	var myLatLng = {
		lat: -25.363,
		lng: 131.044
	};
	map = new google.maps.Map(document.getElementById('map'), {
		zoom: 4,
		center: myLatLng
	});
	// This event listener calls addMarker() when the map is clicked.
	google.maps.event.addListener(map, 'click', function(event) {
		addMarker(event.latLng);
	});
	addMarker(myLatLng);
}
// Adds a marker to the map and push to the array.
function addMarker(location) {
	var marker = new google.maps.Marker({
		position: location,
		map: map,
		draggable: true,
		animation: google.maps.Animation.DROP,
		label: markersArray.length + "",
		title: markersArray.length + ""
	});
	markersArray.push(marker);
	marker.addListener('click', function() {
		clickMarkerEvent();
	});
}
// Sets the map on all markers in the array.
function setMapOnAll(map) {
	for (var i = 0; i < markersArray.length; i++) {
		setMapOnMarker(i, map);
	}
}
// Removes the markers from the map, but keeps them in the array.
function clearMarkers() {
	setMapOnAll(null);
}
// Shows any markers currently in the array.
function showMarkers() {
	setMapOnAll(map);
}
function setMapOnMarker(markerIndex, map) {
	markersArray[markerIndex].setMap(map);
}
function hideMarker(markerIndex) {
	setMapOnMarker(markerIndex, null);
}
function deleteMarker(markerIndex) {
	hideMarker(markerIndex);
	markersArray[markerIndex] = null;
}
/*	
	Deletes all markers in the array by removing references to them.
	Note that the above method does not delete the marker. It simply removes the 
	marker from the map. If instead you wish to delete the marker, you should remove 
	it from the map, and then set the marker itself to null.
	https://developers.google.com/maps/documentation/javascript/markers#remove
*/
function deleteMarkers() {
	clearMarkers();
	for (var i = 0; i < markersArray.length; i++) {
		markersArray[i] = null;
	}
	markersArray = [];
}
//listeners
function clickMarkerEvent() {
	lastMarkerClicked = event.target || event.srcElement;
	if (markersArray[lastMarkerClicked.title].getAnimation() !== null) {
		markersArray[lastMarkerClicked.title].setAnimation(null);
	}
	else {
		markersArray[lastMarkerClicked.title].setAnimation(google.maps.Animation.BOUNCE);
	}
	
	contentString = '<div id="content">' +
	'<div id="siteNotice">' +
	'</div>' +
	'<h1 id="firstHeading" class="firstHeading">Marker Info</h1>' +
	'<div id="bodyContent">' +
	'<b>Locatoin:</b> <p>' + markersArray[lastMarkerClicked.title].getPosition() + '</p>' + 
	'<b>Title: </b> <p>' + lastMarkerClicked.title + '</p>' + 
	'<button onclick="hideMarkerClickEvent()">Hide Marker</button>' +
	'<button onclick="deleteMarkerClickEvent()">Delete Marker</button>' +
	'</div>' +
	'</div>';
	
	if(infowindow !== null && typeof infowindow !== 'undefined')
		infowindow.close();
	
	infowindow = new google.maps.InfoWindow({
		content: contentString,
		maxWidth: 200
	});
	infowindow.open(map, markersArray[lastMarkerClicked.title]);
}
function deleteMarkerClickEvent() {
	deleteMarker(lastMarkerClicked.title);
}
function hideMarkerClickEvent() {
	hideMarker(lastMarkerClicked.title);
}
html,
body {
	height: 100%;
	margin: 0;
	padding: 0;
}
#map {
	height: 100%;
}
<!DOCTYPE html>
<html>
<head>
	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
	<meta charset="utf-8">
	<title>Simple markers</title>
	<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
	<div id="map"></div>
	<script type="text/javascript" src="markers.js"></script>
	<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCGj-Dsa4PtrJiyATE_upQgOkfEkjFXqoQ&callback=initMap">
	</script>
</body>
</html>

您的第一种方法几乎可以,问题是在调用click listener时,所有标记都已在markersArray中,因此markersArray.length - 1总是指向最后一个标记。只需创建一个变量,该变量的值将标记的id保存在addMarker函数的范围内。以下是工作代码(注意var index = markersArray.length;的使用):

'use strict'
var infowindow;
var contentString;
var markersArray = [];
var map;
//	Initializes the map with a marker
function initMap() {
	var myLatLng = {
		lat: -25.363,
		lng: 131.044
	};
	map = new google.maps.Map(document.getElementById('map'), {
		zoom: 4,
		center: myLatLng
	});
	// This event listener calls addMarker() when the map is clicked.
	google.maps.event.addListener(map, 'click', function(event) {
		addMarker(event.latLng);
	});
	addMarker(myLatLng);
}
// Adds a marker to the map and push to the array.
function addMarker(location) {
    var index = markersArray.length;
	var marker = new google.maps.Marker({
		position: location,
		map: map,
		draggable: true,
		animation: google.maps.Animation.DROP,
		label: index + "",
		title: index + ""
	});
	markersArray.push(marker);
	marker.addListener('click', function() {
		clickMarkerEvent(index);
	});
}
// Sets the map on all markers in the array.
function setMapOnAll(map) {
	for (var i = 0; i < markersArray.length; i++) {
		setMapOnMarker(i, map);
	}
}
// Removes the markers from the map, but keeps them in the array.
function clearMarkers() {
	setMapOnAll(null);
}
// Shows any markers currently in the array.
function showMarkers() {
	setMapOnAll(map);
}
function setMapOnMarker(markerIndex, map) {
	markersArray[markerIndex].setMap(map);
}
function hideMarker(markerIndex) {
	setMapOnMarker(markerIndex, null);
}
function deleteMarker(markerIndex) {
	hideMarker(markerIndex);
	markersArray[markerIndex] = null;
}
function deleteMarkers() {
	clearMarkers();
	for (var i = 0; i < markersArray.length; i++) {
		markersArray[i] = null;
	}
	markersArray = [];
}
//listeners
function clickMarkerEvent(index) {
	if (markersArray[index].getAnimation() !== null) {
		markersArray[index].setAnimation(null);
	}
	else {
		markersArray[index].setAnimation(google.maps.Animation.BOUNCE);
	}
	
	contentString = '<div id="content">' +
	'<div id="siteNotice">' +
	'</div>' +
	'<h1 id="firstHeading" class="firstHeading">Marker Info</h1>' +
	'<div id="bodyContent">' +
	'<b>Locatoin:</b> <p>' + markersArray[index].getPosition() + '</p>' + 
	'<b>Title: </b> <p>' + markersArray[index].getTitle() + '</p>' + 
	'<button onclick="hideMarkerClickEvent(' + index + ')">Hide Marker</button>' +
	'<button onclick="deleteMarkerClickEvent(' + index + ')">Delete Marker</button>' +
	'</div>' +
	'</div>';
	
	if(infowindow !== null && typeof infowindow !== 'undefined')
		infowindow.close();
	
	infowindow = new google.maps.InfoWindow({
		content: contentString,
		maxWidth: 200
	});
	infowindow.open(map, markersArray[index]);
}
function deleteMarkerClickEvent(index) {
	deleteMarker(index);
}
function hideMarkerClickEvent(index) {
	hideMarker(index);
}
html,
body {
	height: 100%;
	margin: 0;
	padding: 0;
}
#map {
	height: 100%;
}
<!DOCTYPE html>
<html>
<head>
	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
	<meta charset="utf-8">
	<title>Simple markers</title>
	<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
	<div id="map"></div>
	<script type="text/javascript" src="markers.js"></script>
	<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCGj-Dsa4PtrJiyATE_upQgOkfEkjFXqoQ&callback=initMap">
	</script>
</body>
</html>

我终于找到了一个我喜欢的解决方案(与我接受的不同)。

经过大量研究,我发现了这个网站:https://www.toptal.com/javascript/interview-questions

我读了第10个问题:

当执行下面的代码?为什么?

(function() {
    console.log(1); 
    setTimeout(function(){console.log(2)}, 1000); 
    setTimeout(function(){console.log(3)}, 0); 
    console.log(4);
})();

如果你想知道答案,请随时阅读原始资料。

看完这篇文章后,我提出了使用范围的版本:

var markersArray = [];
// Adds a marker to the map and push to the array.
function addMarker(location) {
    var marker = new google.maps.Marker({
        position: location,
        map: map,
        draggable: true,
        animation: google.maps.Animation.DROP,
        label: markersArray.length + "",
        title: "Marker Number " + markersArray.length
    });
    markersArray.push(marker);
    marker.addListener('click', (function(index) {
        return function() {
            clickMarkerEvent(index);
        };
    })(markersArray.length - 1));
}
//listeners
function clickMarkerEvent(index) {
    alert(index);
}

这是我最初想做的,但我忘记了一些细节。

尽管如此,我还是决定接受另一个问题,因为它很简单。

这是我的完整项目。我添加了一些更多的功能,比如标记的自定义控件。无论如何,这并不完美,但我认为这对任何感兴趣的人来说都是一个很好的起点。

'use strict'
/*global google*/
/*
	Best practices: For the best user experience, only one info window should be 
	open on the map at any one time. Multiple info windows make the map appear 
	cluttered. If you only need one info window at a time, you can create just 
	one InfoWindow object and open it at different locations or markers upon map
	events, such as user clicks. If you do need more than one info window, you 
	can display multiple InfoWindow objects at the same time.
*/
var infowindow;
var contentString;
var lastMarkerClicked;
var markersArray = [];
var map;
//	Initializes the map with a marker
function initMap() {
	var myLatLng = {
		lat: -25.363,
		lng: 131.044
	};
	map = new google.maps.Map(document.getElementById('map'), {
		zoom: 4,
		center: myLatLng
	});
	// This event listener calls addMarker() when the map is clicked.
	google.maps.event.addListener(map, 'click', function(event) {
		addMarker(event.latLng);
	});
	addMarker(myLatLng);
}
// Adds a marker to the map and push to the array.
function addMarker(location) {
	var marker = new google.maps.Marker({
		position: location,
		map: map,
		draggable: true,
		animation: google.maps.Animation.DROP,
		label: markersArray.length + "",
		title: "Marker Number " + markersArray.length
	});
	
	markersArray.push(marker);
	marker.addListener('click', (function(index) {
		return function() {
			clickMarkerEvent(index);
		};
	})(markersArray.length - 1));
}
// Sets the map on all markers in the array.
function setMapOnAll(map) {
	for (var i = 0; i < markersArray.length; i++) {
		if(markersArray[i] !== null)
		setMapOnMarker(i, map);
	}
}
// Removes the markers from the map, but keeps them in the array.
function clearMarkers() {
	setMapOnAll(null);
}
// Shows any markers currently in the array.
function showMarkers() {
	setMapOnAll(map);
}
/*	
	Deletes all markers in the array by removing references to them.
	Note that the above method does not delete the marker. It simply removes the 
	marker from the map. If instead you wish to delete the marker, you should remove 
	it from the map, and then set the marker itself to null.
	https://developers.google.com/maps/documentation/javascript/markers#remove
*/
function deleteMarkers() {
	clearMarkers();
	for (var i = 0; i < markersArray.length; i++) {
		if(markersArray[i] !== null)
			markersArray[i] = null;
	}
	
	markersArray = [];
}
// Sets a marker with the given map
function setMapOnMarker(markerIndex, map) {
	markersArray[markerIndex].setMap(map);
}
// Hides a single marker
function hideMarker(markerIndex) {
	setMapOnMarker(markerIndex, null);
}
// Deletes a marker. Hides it first.
function deleteMarker(markerIndex) {
	hideMarker(markerIndex);
	markersArray[markerIndex] = null;
}
//listeners
function clickMarkerEvent(index) {
	lastMarkerClicked = markersArray[index];
	if (lastMarkerClicked.getAnimation() !== null)
		lastMarkerClicked.setAnimation(null);
	else 
		lastMarkerClicked.setAnimation(google.maps.Animation.BOUNCE);
	contentString = '<div id="content">' +
		'<div id="siteNotice">' +
		'</div>' +
		'<h1 id="firstHeading" class="firstHeading">Marker Info</h1>' +
		'<div id="bodyContent">' +
		'<b>Locatoin:</b> <p>' + lastMarkerClicked.getPosition() + '</p>' +
		'<b>Title: </b> <p>' + lastMarkerClicked.getTitle() + '</p>' +
		'<button onclick="hideMarkerClickEvent()">Hide Marker</button>' +
		'<button onclick="deleteMarkerClickEvent()">Delete Marker</button>' +
		'</div>' +
		'</div>';
	if (infowindow !== null && typeof infowindow !== 'undefined')
		infowindow.close();
	infowindow = new google.maps.InfoWindow({
		content: contentString,
		maxWidth: 200
	});
	infowindow.open(map, lastMarkerClicked);
}
function deleteMarkerClickEvent() {
	deleteMarker(markersArray.indexOf(lastMarkerClicked));
}
function hideMarkerClickEvent() {
	hideMarker(markersArray.indexOf(lastMarkerClicked));
}
html,
body {
	height: 100%;
	margin: 0;
	padding: 0;
}
#map {
	height: 100%;
}
#floating-panel {
	position: absolute;
	top: 10px;
	left: 25%;
	z-index: 5;
	background-color: #fff;
	padding: 5px;
	border: 1px solid #999;
	text-align: center;
	font-family: 'Roboto', 'sans-serif';
	line-height: 30px;
	padding-left: 10px;
}
<!DOCTYPE html>
<html>
<head>
	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
	<meta charset="utf-8">
	<title>Simple markers</title>
	<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
	<div id="floating-panel">
		<input onclick="clearMarkers();" type=button value="Hide Markers">
		<input onclick="showMarkers();" type=button value="Show All Markers">
		<input onclick="deleteMarkers();" type=button value="Delete Markers">
	</div>
	<div id="map"></div>
	<script type="text/javascript" src="markers.js"></script>
	<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCGj-Dsa4PtrJiyATE_upQgOkfEkjFXqoQ&callback=initMap">
	</script>
</body>
</html>