Javascript 使用api v3将infowindow添加到google地图上的标记循环数组中
我有一个在js中循环的数组,用于在google地图上放置自定义标记。我需要为每个标记添加一个隐藏的信息窗口,以便在单击时显示相关的信息窗口。目前我正在做以下工作:Javascript 使用api v3将infowindow添加到google地图上的标记循环数组中,javascript,google-maps,google-maps-api-3,Javascript,Google Maps,Google Maps Api 3,我有一个在js中循环的数组,用于在google地图上放置自定义标记。我需要为每个标记添加一个隐藏的信息窗口,以便在单击时显示相关的信息窗口。目前我正在做以下工作: for(var i=0; i<google_map_item.length; i++) { latlon = new google.maps.LatLng(google_map_item[i].lat, google_map_item[i].lon) bounds.extend(latlo
for(var i=0; i<google_map_item.length; i++)
{
latlon = new google.maps.LatLng(google_map_item[i].lat, google_map_item[i].lon)
bounds.extend(latlon);
var iconcolor = google_map_item[i].iconColor;
marker = new google.maps.Marker({
map: map,
position: latlon,
icon: "https://chart.googleapis.com/chart?chst=d_map_pin_letter_withshadow&chld=" + (i + 1) + "|"+iconcolor+"|000000",
type: 'flat',
icon_color: '#ff0000',
label_color: '#ffffff',
width: '20',
height: '20',
label_size: '11',
clickable: true
});
marker.info = new google.maps.InfoWindow({
content: '<b>Speed:</b> knots'
});
google.maps.event.addListener(marker, 'click', function() {
marker.info.open(map, marker);
});
map.fitBounds(bounds);
}
for(var i=0;i请查看以下博文:
基本上,您正在用新的标记对象覆盖每个标记对象。您需要使用this
使每个标记上下文特定
您的事件侦听器应该如下所示:
google.maps.event.addListener(marker, 'click', function() {
marker.info.open(map, this);
});
您可能需要进行更多更改,以确保为每次迭代创建新对象。请尝试此操作,并从右侧的建议中告诉我们!:
似乎是您正在寻找的答案(使用函数闭包)
我认为处理InfoWindow的常见做法是创建一个全局窗口
并将其绑定为使用每个标记单击事件,而不是为每个标记创建一个。
我用谷歌标记制作了一个简单的应用程序,这就是我使用的。希望这有帮助
var globalInfoWindow = new google.maps.InfoWindow();
var offset = new google.maps.Size(17,-10);
globalInfoWindow.setOptions({pixelOffset: offset});
.
.
.
for(var i in data.locations)
{
var latlng = data.locations[i];
var lat = Number(latlng[0]);
var lng = Number(latlng[1]);
var marker_latlng = new google.maps.LatLng(lat, lng);
var marker = new google.maps.Marker({
position: marker_latlng,
icon: markerImg,
map: map
});
// binds the showing of infowindow with click event.
google.maps.event.addListener(marker, 'click', viewLocPic);
}
.
.
.
// 'this' in the function refers to the marker itself.
function viewLocPic()
{
console.log("this refers to " + this);
globalInfoWindow.setPosition(this.getPosition());
globalInfoWindow.setContent("<img src='cycling.png'/>");
globalInfoWindow.open(map, this);
}
var globalinfown=new google.maps.InfoWindow();
var offset=新的google.maps.Size(17,-10);
setOptions({pixelOffset:offset});
.
.
.
用于(数据位置中的var i)
{
var latlng=数据位置[i];
var lat=编号(latlng[0]);
var lng=数量(latlng[1]);
var marker_latlng=新的google.maps.latlng(lat,lng);
var marker=new google.maps.marker({
位置:标记器,
图标:markerImg,
地图:地图
});
//使用click事件绑定infowindow的显示。
google.maps.event.addListener(标记'click',viewLocPic);
}
.
.
.
//函数中的“this”指的是标记本身。
函数viewLocPic()
{
console.log(“这是指”+this);
globalInfoWindow.setPosition(this.getPosition());
globalInfoWindow.setContent(“”);
globalInfoWindow.open(映射,此);
}
啊,这个问题
如果你不知道自己在寻找什么,这是一个艰难的过程。几个月前我就有过这样的经历,无论是在StackOverflow上,还是在Google地图文档中,都很难找到正确的答案
我不想知道为什么这段代码比下一个男人更有效,但它对我有效,并且在你的部分进行一些调整以适应你的项目,它也应该对你有效
这是我使用的代码。在变量名方面,我的项目中有一些工件,但我已经尝试尽可能地去除其中的大部分,并注释掉您不需要的部分,或者您可以根据所需的信息窗口行为进行更改的部分
function initMap(){
bldgNo = new Object(); // YOU CAN GET
bldgName = new Object(); // RID OF ANY
bldgAddr = new Object(); // OF THESE...
bldgGfx = new Object(); //
mainMeter = new Object(); // JUST REPLACE
alarmCount = new Object(); // THEM WITH
latitude = new Object(); // WHAT YOU'LL
longitude = new Object(); // NEED INSTEAD.
markersArray = [];
google.maps.Map.prototype.clearOverlays = function() {
if (markersArray) {
for (i in markersArray) {
markersArray[i].setMap(null);
}
markersArray.length = 0;
}
}
location1 = new google.maps.LatLng(22.413543,-137.075743); // IN CASE YOU'LL NEED MORE
location2 = new google.maps.LatLng(22.628202,-137.426432); // THAN ONE LOCATION? I DID.
myOptions = {
zoom:15, // BEST IS BETWEEN 12-15
scrollwheel:false, // EITHER TRUE OR FALSE
center:location1, // ONE OF THE ABOVE LAT/LNG LOCATIONS
mapTypeId: google.maps.MapTypeId.HYBRID // ROADMAP, SATELLITE, HYBRID, or TERRAIN (all-caps)
};
map = new google.maps.Map(document.getElementById("map_canvas"),myOptions);
icon = new google.maps.MarkerImage('images/YOUR-IMAGE-HERE.png',new google.maps.Size(20,34),new google.maps.Point(0,0),new google.maps.Point(10,34));
shadow = new google.maps.MarkerImage('images/YOUR-SHADOW-IMG.png',new google.maps.Size(37,34),new google.maps.Point(0,0),new google.maps.Point(10,34));
infowindow=new google.maps.InfoWindow();
var i=1;
$(".building").each(function(i){
bldgNo[i] = $(this).children(".bldg-no").html(); // YOU CAN GET
bldgName[i] = $(this).children(".bldg-name").html(); // RID OF ANY
bldgAddr[i] = $(this).children(".bldg-address").html(); // OF THESE...
bldgGfx[i] = $(this).children(".bldg-graphic").html(); //
mainMeter[i] = $(this).children(".main-meter").html(); // JUST REPLACE
alarmCount[i] = $(this).children(".alarm-count").html(); // THEM WITH
latitude[i] = $(this).children(".latitude").html(); // WHAT YOU'LL
longitude[i] = $(this).children(".longitude").html(); // NEED INSTEAD.
marker=new google.maps.Marker({
position:new google.maps.LatLng(
latitude[i], // (DEFINED ABOVE)
longitude[i] // (DEFINED ABOVE)
),
map:map, // THE DEFAULT
shadow:shadow, // JUST MY NAME FOR IT (DEFINED ABOVE)
icon:icon, // JUST MY NAME FOR IT (DEFINED ABOVE)
title:bldgName[i]+" \n"+bldgAddr[i], // FEEL FREE TO CHANGE THIS BASED ON WHAT YOU NEED
optimized:false // YOU MAY OR MAY NOT NEED THIS
});
marker.setAnimation(google.maps.Animation.NULL); // NULL, DROP, or BOUNCE (all-caps)
markersArray.push(marker);
google.maps.event.addListener(marker,'click',(function(marker,i){
return function(){
infowindow.setContent('
//
// INSERT INFOWINDOW CONTENT HERE
//
');infowindow.open(map,marker);
}
})(marker,i));
i++;
});
}
function updateMap(){
map.clearOverlays();
infowindow=new google.maps.InfoWindow();
var i=1;
$(".building").each(function(i){
bldgNo[i] = $(this).children(".bldg-no").html(); // YOU CAN GET
bldgName[i] = $(this).children(".bldg-name").html(); // RID OF ANY
bldgAddr[i] = $(this).children(".bldg-address").html(); // OF THESE...
bldgGfx[i] = $(this).children(".bldg-graphic").html(); //
mainMeter[i] = $(this).children(".main-meter").html(); // JUST REPLACE
alarmCount[i] = $(this).children(".alarm-count").html(); // THEM WITH
latitude[i] = $(this).children(".latitude").html(); // WHAT YOU'LL
longitude[i] = $(this).children(".longitude").html(); // NEED INSTEAD.
marker=new google.maps.Marker({
position:new google.maps.LatLng(
latitude[i], // (DEFINED ABOVE)
longitude[i] // (DEFINED ABOVE)
),
map:map, // THE DEFAULT
shadow:shadow, // JUST MY NAME FOR IT (DEFINED ABOVE)
icon:icon, // JUST MY NAME FOR IT (DEFINED ABOVE)
title:bldgName[i]+" \n"+bldgAddr[i], // FEEL FREE TO CHANGE THIS BASED ON WHAT YOU NEED
optimized:false // YOU MAY OR MAY NOT NEED THIS
});
marker.setAnimation(google.maps.Animation.NULL); // NULL, DROP, or BOUNCE (all-caps)
markersArray.push(marker);
google.maps.event.addListener(marker,'click',(function(marker,i){
return function(){
infowindow.setContent('
//
// INSERT UPDATED INFOWINDOW CONTENT HERE
//
');infowindow.open(map,marker);
}
})(marker,i));
i++;
});
}
我确信需要解决一些问题,但我电脑上的代码(没有为您的利益而编辑的版本)工作得很好。如果我在复制和编辑代码时错误地打断了代码,以便于您使用,请告诉我,我会更新我的答案
干杯
编辑:顺便说一句,这段代码既创建了隐藏信息窗口(函数initMap
),又更新了隐藏信息窗口(函数updateMap
)。如果您以设定的间隔调用函数updateMap
,它会更新地图中的信息,这是我的项目所必需的
因此,存在非常相似/重复的代码块,因为每次页面的InfoWindows更新时,我都需要删除隐藏的代码块并创建新的代码块
您可以通过删除updateMap
函数和initMap
中专门为在updateMap
中进行操作而创建的任何工件,非常轻松地将其简化为您的需要。然后只需调用initMap
函数,您就一切就绪了!它为每个工件创建了一个框,但每个框中的内容都相同ne.内容是动态的,因此每个区域都会有所不同…?您需要确保每次都创建一个新的标记引用。阅读该博客文章;它讨论如何通过将动态内容存储在标记对象中来使用它。当我遇到问题时,我阅读了该博客文章,唯一帮助我的是使用回调函数作为d描述在我的答案。如果这对你有效马特,请让我知道,因为它看起来比我使用的代码简单得多。