如何知道哪个标记被谷歌地图点击了
How to know which marker was clicked GoogleMaps
我正在用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>
- 谷歌地图固定位置覆盖
- 不显示带有本地json文件数据的谷歌地图脚本
- 谷歌地图不是以HTML显示,而是在JS Fiddle上工作
- 谷歌地图标记不会显示
- 无法在JS中显示谷歌地图
- 科尔多瓦页面类应用程序中的多个谷歌地图
- 需要帮助谷歌地图方向面板在FancyBox中显示
- 在谷歌地图上获取事件的x,y坐标
- 谷歌地图API v3不适用于移动浏览器或PhoneGap
- 如何知道哪个标记被谷歌地图点击了
- 谷歌地图-不知道为什么我总是得到第一个信息窗口
- 我怎么知道谷歌地图上已经弹出了信息窗口
- 如何知道一个坐标是在多边形内还是在多边形外?PHP +谷歌地图+ JS
- 我们可以知道一个谷歌地图是否已经初始化
- 如何知道是标记内多边形在谷歌地图api
- 谷歌地图如何添加标记,如果我知道纬度和经度
- 如果我只知道它的大小和东北角,如何绘制谷歌地图矩形
- 你知道如何获得谷歌地图在阿根廷的十字路口吗?
- 我想知道谷歌地图交通层中的车辆数量
- 如何知道谷歌地图的几何坐标