如何知道点击GoogleMaps的标记

时间:2016-05-18 08:27:29

标签: javascript google-maps google-maps-api-3

我正在使用JavaScript,CSS和HTML使用Google Maps JavaScript API v3进行小型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);
}

最后一种方法的问题(尽管它有效)如下:

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

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

'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>

2 个答案:

答案 0 :(得分:2)

你的第一种方法几乎没问题,问题是在点击监听器被调用时,所有标记都已经在markersArray中,所以markersArray.length - 1始终指向最后一个标记。只需创建一个变量,该值保存addMarker函数范围内的标记的id。这是工作代码(注意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>

答案 1 :(得分:1)

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

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

我读了第10号问题:

  

当数字1-4以1-4的顺序记录到控制台时   下面的代码执行?为什么呢?

(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>