将 actionListeners 添加到动态创建的 google 标记以绘制路线
Adding actionListeners to dynamically created google markers to plot routes
我有一个页面可以从数据库中检索一些位置,并根据它们 lat/long 创建标记以显示在地图上。标记保存在一个数组中,我使用 for 循环将 onclick 动作侦听器分配给每个标记。当用户单击标记时,我希望显示从他们当前位置到标记位置的路线。我遇到的问题是,无论单击哪个标记,它总是绘制一条通往数组中最后一个标记的路径。
这就是地图的样子
在上面的示例中,我将单击红色标记 A。
如您所见,它已经绘制了一条通往标记 D 的航线。
我的代码:
//THIS FUNCTIONS BUILD THE MAPS
function initializeMap(position)
{ //USER LOCATION
var myCenter = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var mapProp =
{
center: myCenter,
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
mapObj = new google.maps.Map(document.getElementById("googleMap"), mapProp);
//MAKING SURE THE DATA ARRAY HAS SOMETHING IN IT
if (ajaxResult.length > 0)
{
for (var i = 0; i < ajaxResult.length; i++)
{
var pos = {lat: parseFloat(ajaxResult[i][6]), lng: parseFloat(ajaxResult[i][7])};
//BUILDING THE DESTINATION MARKERS
var suggestionMarker = new google.maps.Marker({
position: pos,
icon: markerNames[i]
});
markers.push(suggestionMarker);//ADDING TO THE MARKER ARRAY
suggestionMarker.setMap(mapObj);//ADING TO THE MAP
var userString = ajaxResult[i][1];//INFORMATINO WINDOW
var infowindow = new google.maps.InfoWindow({
content: userString
});
infowindow.open(mapObj, suggestionMarker);
}
addMarkerListeners(myCenter);
}
//MARKER FOR THE USER LOCATION
var userImage = 'assets/img/GoogleMapsMarkers/blue_MarkerA.png'
var userMarker = new google.maps.Marker({
position: myCenter,
icon: userImage
});
markers.push(userMarker);
userMarker.setMap(mapObj);
//USER INFORMATION WINDOW
var userString = "You!";
var infowindow = new google.maps.InfoWindow({
content: userString
});
infowindow.open(mapObj, userMarker);
}
/*
*
* @param {type} option
* @returns {Boolean}
* ACCEPTS THE USER LOCATION AND ADDS ACTION LISTENERS TO EACH MARKER
* IN THE MARKER ARRAY. THE ACTION LISTENER CALLS THE PLOT ROUTE
* FUNCTION AND PASSES IT THE MARKER POSITION AND USER POSITION
*/
function addMarkerListeners(myCenter)
{
if(markers.length > 0)
{
for(var i = 0; i < markers.length-1; i++)
{
google.maps.event.addListener(markers[i],'click', function(){plotRoute(markers[i].getPosition(),myCenter);});
//markers[i].addEventListener('click', function(){plotRoute(markers[i].getPosition(),myCenter);});
directionsDisplay.setMap(mapObj);
}
}
}
//CREATES A ROUT
function plotRoute(pos, myCenter)
{
var request = {
origin: myCenter,
destination: pos,
travelMode: 'DRIVING'
};
directionsService.route(request, function(result,status){
if(status === 'OK')
{
directionsDisplay.setDirections(result);
}
});
}
请注意,实际的最终标记始终是用户标记,但指示 for 循环不包含它。谁能看出为什么它只在标记数组中绘制到最终目的地标记的路线?
这是循环设置事件侦听器的常见问题。它在这个相关问题中得到解决:Google Maps JS API v3 - Simple Multiple Marker Example using function closure。要在您的代码中使用该解决方案:
function addMarkerListeners(myCenter) {
if (markers.length > 0) {
for (var i = 0; i < markers.length; i++) {
// function closure on the "i" variable
google.maps.event.addListener(markers[i], 'click', (function(i) {
return function() {
plotRoute(markers[i].getPosition(), myCenter);
}})(i));
directionsDisplay.setMap(mapObj);
}
}
}
为了不关闭函数解决它,你可以在事件处理函数中使用this
,它指的是被点击的标记:
function addMarkerListeners(myCenter) {
if (markers.length > 0) {
for (var i = 0; i < markers.length; i++) {
google.maps.event.addListener(markers[i], 'click', function() {
plotRoute(this.getPosition(), myCenter);
});
directionsDisplay.setMap(mapObj);
}
}
}
代码片段(使用函数闭包):
var geocoder;
var map;
var markers = [];
var directionsDisplay = new google.maps.DirectionsRenderer();
var directionsService = new google.maps.DirectionsService();
function initialize() {
// Googleplex 37.4223434, -122.0843689
var position = {coords: {latitude:37.4223434, longitude:-122.0843689}}
initializeMap(position);
}
google.maps.event.addDomListener(window, "load", initialize);
// Menlo Park, CA, USA (37.4529598, -122.18172520000002)
// Mountain View, CA, USA (37.3860517, -122.0838511)
var ajaxResult = [[0,"infowindow 0",2,3,4,5,37.4419,-122.1419],
[1,"infowindow 1",2,3,4,5,37.4529598,-122.1817252],[2,"infowindow 2",2,3,4,5,37.3860517,-122.0838511]]
//THIS FUNCTIONS BUILD THE MAPS
function initializeMap(position) { //USER LOCATION
var myCenter = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var mapProp = {
center: myCenter,
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
mapObj = new google.maps.Map(document.getElementById("googleMap"), mapProp);
//MAKING SURE THE DATA ARRAY HAS SOMETHING IN IT
if (ajaxResult.length > 0) {
for (var i = 0; i < ajaxResult.length; i++) {
var pos = {
lat: parseFloat(ajaxResult[i][6]),
lng: parseFloat(ajaxResult[i][7])
};
//BUILDING THE DESTINATION MARKERS
var suggestionMarker = new google.maps.Marker({
position: pos,
// icon: markerNames[i]
});
markers.push(suggestionMarker); //ADDING TO THE MARKER ARRAY
suggestionMarker.setMap(mapObj); //ADING TO THE MAP
var userString = ajaxResult[i][1]; //INFORMATINO WINDOW
var infowindow = new google.maps.InfoWindow({
content: userString
});
infowindow.open(mapObj, suggestionMarker);
}
addMarkerListeners(myCenter);
}
//MARKER FOR THE USER LOCATION
var userImage = 'http://maps.google.com/mapfiles/ms/micons/blue.png'
var userMarker = new google.maps.Marker({
position: myCenter,
icon: userImage
});
markers.push(userMarker);
userMarker.setMap(mapObj);
//USER INFORMATION WINDOW
var userString = "You!";
var infowindow = new google.maps.InfoWindow({
content: userString
});
infowindow.open(mapObj, userMarker);
}
/*
*
* @param {type} option
* @returns {Boolean}
* ACCEPTS THE USER LOCATION AND ADDS ACTION LISTENERS TO EACH MARKER
* IN THE MARKER ARRAY. THE ACTION LISTENER CALLS THE PLOT ROUTE
* FUNCTION AND PASSES IT THE MARKER POSITION AND USER POSITION
*/
function addMarkerListeners(myCenter) {
if (markers.length > 0) {
for (var i = 0; i < markers.length; i++) {
google.maps.event.addListener(markers[i], 'click', (function(i) {
return function() {
plotRoute(markers[i].getPosition(), myCenter);
}})(i));
directionsDisplay.setMap(mapObj);
}
}
}
//CREATES A ROUTE
function plotRoute(pos, myCenter) {
var request = {
origin: myCenter,
destination: pos,
travelMode: 'DRIVING'
};
directionsService.route(request, function(result, status) {
if (status === 'OK') {
directionsDisplay.setDirections(result);
} else alert("directions request failed: "+status);
});
}
html,
body,
#googleMap {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="googleMap"></div>
代码片段(使用this
):
var geocoder;
var map;
var markers = [];
var directionsDisplay = new google.maps.DirectionsRenderer();
var directionsService = new google.maps.DirectionsService();
function initialize() {
// Googleplex 37.4223434, -122.0843689
var position = {coords: {latitude:37.4223434, longitude:-122.0843689}}
initializeMap(position);
}
google.maps.event.addDomListener(window, "load", initialize);
// Menlo Park, CA, USA (37.4529598, -122.18172520000002)
// Mountain View, CA, USA (37.3860517, -122.0838511)
var ajaxResult = [[0,"infowindow 0",2,3,4,5,37.4419,-122.1419],
[1,"infowindow 1",2,3,4,5,37.4529598,-122.1817252],[2,"infowindow 2",2,3,4,5,37.3860517,-122.0838511]]
//THIS FUNCTIONS BUILD THE MAPS
function initializeMap(position) { //USER LOCATION
var myCenter = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var mapProp = {
center: myCenter,
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
mapObj = new google.maps.Map(document.getElementById("googleMap"), mapProp);
//MAKING SURE THE DATA ARRAY HAS SOMETHING IN IT
if (ajaxResult.length > 0) {
for (var i = 0; i < ajaxResult.length; i++) {
var pos = {
lat: parseFloat(ajaxResult[i][6]),
lng: parseFloat(ajaxResult[i][7])
};
//BUILDING THE DESTINATION MARKERS
var suggestionMarker = new google.maps.Marker({
position: pos,
// icon: markerNames[i]
});
markers.push(suggestionMarker); //ADDING TO THE MARKER ARRAY
suggestionMarker.setMap(mapObj); //ADING TO THE MAP
var userString = ajaxResult[i][1]; //INFORMATINO WINDOW
var infowindow = new google.maps.InfoWindow({
content: userString
});
infowindow.open(mapObj, suggestionMarker);
}
addMarkerListeners(myCenter);
}
//MARKER FOR THE USER LOCATION
var userImage = 'http://maps.google.com/mapfiles/ms/micons/blue.png'
var userMarker = new google.maps.Marker({
position: myCenter,
icon: userImage
});
markers.push(userMarker);
userMarker.setMap(mapObj);
//USER INFORMATION WINDOW
var userString = "You!";
var infowindow = new google.maps.InfoWindow({
content: userString
});
infowindow.open(mapObj, userMarker);
}
/*
*
* @param {type} option
* @returns {Boolean}
* ACCEPTS THE USER LOCATION AND ADDS ACTION LISTENERS TO EACH MARKER
* IN THE MARKER ARRAY. THE ACTION LISTENER CALLS THE PLOT ROUTE
* FUNCTION AND PASSES IT THE MARKER POSITION AND USER POSITION
*/
function addMarkerListeners(myCenter) {
if (markers.length > 0) {
for (var i = 0; i < markers.length; i++) {
google.maps.event.addListener(markers[i], 'click', function() {
plotRoute(this.getPosition(), myCenter);
});
directionsDisplay.setMap(mapObj);
}
}
}
//CREATES A ROUT
function plotRoute(pos, myCenter) {
var request = {
origin: myCenter,
destination: pos,
travelMode: 'DRIVING'
};
directionsService.route(request, function(result, status) {
if (status === 'OK') {
directionsDisplay.setDirections(result);
}
});
}
html,
body,
#googleMap {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="googleMap"></div>
我有一个页面可以从数据库中检索一些位置,并根据它们 lat/long 创建标记以显示在地图上。标记保存在一个数组中,我使用 for 循环将 onclick 动作侦听器分配给每个标记。当用户单击标记时,我希望显示从他们当前位置到标记位置的路线。我遇到的问题是,无论单击哪个标记,它总是绘制一条通往数组中最后一个标记的路径。
这就是地图的样子
在上面的示例中,我将单击红色标记 A。
如您所见,它已经绘制了一条通往标记 D 的航线。
我的代码:
//THIS FUNCTIONS BUILD THE MAPS
function initializeMap(position)
{ //USER LOCATION
var myCenter = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var mapProp =
{
center: myCenter,
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
mapObj = new google.maps.Map(document.getElementById("googleMap"), mapProp);
//MAKING SURE THE DATA ARRAY HAS SOMETHING IN IT
if (ajaxResult.length > 0)
{
for (var i = 0; i < ajaxResult.length; i++)
{
var pos = {lat: parseFloat(ajaxResult[i][6]), lng: parseFloat(ajaxResult[i][7])};
//BUILDING THE DESTINATION MARKERS
var suggestionMarker = new google.maps.Marker({
position: pos,
icon: markerNames[i]
});
markers.push(suggestionMarker);//ADDING TO THE MARKER ARRAY
suggestionMarker.setMap(mapObj);//ADING TO THE MAP
var userString = ajaxResult[i][1];//INFORMATINO WINDOW
var infowindow = new google.maps.InfoWindow({
content: userString
});
infowindow.open(mapObj, suggestionMarker);
}
addMarkerListeners(myCenter);
}
//MARKER FOR THE USER LOCATION
var userImage = 'assets/img/GoogleMapsMarkers/blue_MarkerA.png'
var userMarker = new google.maps.Marker({
position: myCenter,
icon: userImage
});
markers.push(userMarker);
userMarker.setMap(mapObj);
//USER INFORMATION WINDOW
var userString = "You!";
var infowindow = new google.maps.InfoWindow({
content: userString
});
infowindow.open(mapObj, userMarker);
}
/*
*
* @param {type} option
* @returns {Boolean}
* ACCEPTS THE USER LOCATION AND ADDS ACTION LISTENERS TO EACH MARKER
* IN THE MARKER ARRAY. THE ACTION LISTENER CALLS THE PLOT ROUTE
* FUNCTION AND PASSES IT THE MARKER POSITION AND USER POSITION
*/
function addMarkerListeners(myCenter)
{
if(markers.length > 0)
{
for(var i = 0; i < markers.length-1; i++)
{
google.maps.event.addListener(markers[i],'click', function(){plotRoute(markers[i].getPosition(),myCenter);});
//markers[i].addEventListener('click', function(){plotRoute(markers[i].getPosition(),myCenter);});
directionsDisplay.setMap(mapObj);
}
}
}
//CREATES A ROUT
function plotRoute(pos, myCenter)
{
var request = {
origin: myCenter,
destination: pos,
travelMode: 'DRIVING'
};
directionsService.route(request, function(result,status){
if(status === 'OK')
{
directionsDisplay.setDirections(result);
}
});
}
请注意,实际的最终标记始终是用户标记,但指示 for 循环不包含它。谁能看出为什么它只在标记数组中绘制到最终目的地标记的路线?
这是循环设置事件侦听器的常见问题。它在这个相关问题中得到解决:Google Maps JS API v3 - Simple Multiple Marker Example using function closure。要在您的代码中使用该解决方案:
function addMarkerListeners(myCenter) {
if (markers.length > 0) {
for (var i = 0; i < markers.length; i++) {
// function closure on the "i" variable
google.maps.event.addListener(markers[i], 'click', (function(i) {
return function() {
plotRoute(markers[i].getPosition(), myCenter);
}})(i));
directionsDisplay.setMap(mapObj);
}
}
}
为了不关闭函数解决它,你可以在事件处理函数中使用this
,它指的是被点击的标记:
function addMarkerListeners(myCenter) {
if (markers.length > 0) {
for (var i = 0; i < markers.length; i++) {
google.maps.event.addListener(markers[i], 'click', function() {
plotRoute(this.getPosition(), myCenter);
});
directionsDisplay.setMap(mapObj);
}
}
}
代码片段(使用函数闭包):
var geocoder;
var map;
var markers = [];
var directionsDisplay = new google.maps.DirectionsRenderer();
var directionsService = new google.maps.DirectionsService();
function initialize() {
// Googleplex 37.4223434, -122.0843689
var position = {coords: {latitude:37.4223434, longitude:-122.0843689}}
initializeMap(position);
}
google.maps.event.addDomListener(window, "load", initialize);
// Menlo Park, CA, USA (37.4529598, -122.18172520000002)
// Mountain View, CA, USA (37.3860517, -122.0838511)
var ajaxResult = [[0,"infowindow 0",2,3,4,5,37.4419,-122.1419],
[1,"infowindow 1",2,3,4,5,37.4529598,-122.1817252],[2,"infowindow 2",2,3,4,5,37.3860517,-122.0838511]]
//THIS FUNCTIONS BUILD THE MAPS
function initializeMap(position) { //USER LOCATION
var myCenter = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var mapProp = {
center: myCenter,
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
mapObj = new google.maps.Map(document.getElementById("googleMap"), mapProp);
//MAKING SURE THE DATA ARRAY HAS SOMETHING IN IT
if (ajaxResult.length > 0) {
for (var i = 0; i < ajaxResult.length; i++) {
var pos = {
lat: parseFloat(ajaxResult[i][6]),
lng: parseFloat(ajaxResult[i][7])
};
//BUILDING THE DESTINATION MARKERS
var suggestionMarker = new google.maps.Marker({
position: pos,
// icon: markerNames[i]
});
markers.push(suggestionMarker); //ADDING TO THE MARKER ARRAY
suggestionMarker.setMap(mapObj); //ADING TO THE MAP
var userString = ajaxResult[i][1]; //INFORMATINO WINDOW
var infowindow = new google.maps.InfoWindow({
content: userString
});
infowindow.open(mapObj, suggestionMarker);
}
addMarkerListeners(myCenter);
}
//MARKER FOR THE USER LOCATION
var userImage = 'http://maps.google.com/mapfiles/ms/micons/blue.png'
var userMarker = new google.maps.Marker({
position: myCenter,
icon: userImage
});
markers.push(userMarker);
userMarker.setMap(mapObj);
//USER INFORMATION WINDOW
var userString = "You!";
var infowindow = new google.maps.InfoWindow({
content: userString
});
infowindow.open(mapObj, userMarker);
}
/*
*
* @param {type} option
* @returns {Boolean}
* ACCEPTS THE USER LOCATION AND ADDS ACTION LISTENERS TO EACH MARKER
* IN THE MARKER ARRAY. THE ACTION LISTENER CALLS THE PLOT ROUTE
* FUNCTION AND PASSES IT THE MARKER POSITION AND USER POSITION
*/
function addMarkerListeners(myCenter) {
if (markers.length > 0) {
for (var i = 0; i < markers.length; i++) {
google.maps.event.addListener(markers[i], 'click', (function(i) {
return function() {
plotRoute(markers[i].getPosition(), myCenter);
}})(i));
directionsDisplay.setMap(mapObj);
}
}
}
//CREATES A ROUTE
function plotRoute(pos, myCenter) {
var request = {
origin: myCenter,
destination: pos,
travelMode: 'DRIVING'
};
directionsService.route(request, function(result, status) {
if (status === 'OK') {
directionsDisplay.setDirections(result);
} else alert("directions request failed: "+status);
});
}
html,
body,
#googleMap {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="googleMap"></div>
代码片段(使用this
):
var geocoder;
var map;
var markers = [];
var directionsDisplay = new google.maps.DirectionsRenderer();
var directionsService = new google.maps.DirectionsService();
function initialize() {
// Googleplex 37.4223434, -122.0843689
var position = {coords: {latitude:37.4223434, longitude:-122.0843689}}
initializeMap(position);
}
google.maps.event.addDomListener(window, "load", initialize);
// Menlo Park, CA, USA (37.4529598, -122.18172520000002)
// Mountain View, CA, USA (37.3860517, -122.0838511)
var ajaxResult = [[0,"infowindow 0",2,3,4,5,37.4419,-122.1419],
[1,"infowindow 1",2,3,4,5,37.4529598,-122.1817252],[2,"infowindow 2",2,3,4,5,37.3860517,-122.0838511]]
//THIS FUNCTIONS BUILD THE MAPS
function initializeMap(position) { //USER LOCATION
var myCenter = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var mapProp = {
center: myCenter,
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
mapObj = new google.maps.Map(document.getElementById("googleMap"), mapProp);
//MAKING SURE THE DATA ARRAY HAS SOMETHING IN IT
if (ajaxResult.length > 0) {
for (var i = 0; i < ajaxResult.length; i++) {
var pos = {
lat: parseFloat(ajaxResult[i][6]),
lng: parseFloat(ajaxResult[i][7])
};
//BUILDING THE DESTINATION MARKERS
var suggestionMarker = new google.maps.Marker({
position: pos,
// icon: markerNames[i]
});
markers.push(suggestionMarker); //ADDING TO THE MARKER ARRAY
suggestionMarker.setMap(mapObj); //ADING TO THE MAP
var userString = ajaxResult[i][1]; //INFORMATINO WINDOW
var infowindow = new google.maps.InfoWindow({
content: userString
});
infowindow.open(mapObj, suggestionMarker);
}
addMarkerListeners(myCenter);
}
//MARKER FOR THE USER LOCATION
var userImage = 'http://maps.google.com/mapfiles/ms/micons/blue.png'
var userMarker = new google.maps.Marker({
position: myCenter,
icon: userImage
});
markers.push(userMarker);
userMarker.setMap(mapObj);
//USER INFORMATION WINDOW
var userString = "You!";
var infowindow = new google.maps.InfoWindow({
content: userString
});
infowindow.open(mapObj, userMarker);
}
/*
*
* @param {type} option
* @returns {Boolean}
* ACCEPTS THE USER LOCATION AND ADDS ACTION LISTENERS TO EACH MARKER
* IN THE MARKER ARRAY. THE ACTION LISTENER CALLS THE PLOT ROUTE
* FUNCTION AND PASSES IT THE MARKER POSITION AND USER POSITION
*/
function addMarkerListeners(myCenter) {
if (markers.length > 0) {
for (var i = 0; i < markers.length; i++) {
google.maps.event.addListener(markers[i], 'click', function() {
plotRoute(this.getPosition(), myCenter);
});
directionsDisplay.setMap(mapObj);
}
}
}
//CREATES A ROUT
function plotRoute(pos, myCenter) {
var request = {
origin: myCenter,
destination: pos,
travelMode: 'DRIVING'
};
directionsService.route(request, function(result, status) {
if (status === 'OK') {
directionsDisplay.setDirections(result);
}
});
}
html,
body,
#googleMap {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="googleMap"></div>