使用api v3在google地图上添加infowindow到循环标记数组

时间:2012-07-16 15:11:27

标签: 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(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);
    }

但是,这只会创建一个信息框,无论您点击哪一个点都会显示。

感谢您的帮助

4 个答案:

答案 0 :(得分:8)

查看此博文:

  

http://you.arenot.me/2010/06/29/google-maps-api-v3-0-multiple-markers-multiple-infowindows/

基本上,您使用新标记对象覆盖每个标记对象。您需要使用this

使每个标记特定于上下文

您的事件监听器应如下所示:

google.maps.event.addListener(marker, 'click', function() {
    marker.info.open(map, this);
});

您可能需要进行更多更改以确保为每次迭代创建新对象。试试这个并告诉我们!

答案 1 :(得分:1)

根据右边的建议: Google Maps API v3 adding an InfoWindow to each marker

似乎是您正在寻找的答案(使用函数关闭)。

Working example, infowindow content from xml

答案 2 :(得分:1)

啊,这个问题....

如果你不知道自己在寻找什么,那就太难了。几个月前我就有了这个,无论是在StackOverflow上还是在Google Maps文档中,都很难找到正确的答案。

我并不是想知道为什么这个代码比下一个人更有效,但它对我有用,并且为了适合你的项目而稍微调整一下,它也适合你。< / p>

这是我使用的代码。我的项目中有一些文件就变量名而言,但是我试图将其中的大部分文章剥离出来,然后注释掉你不需要的部分或者你可以根据你的需要更改的部分。 InfoWindows的所需行为。

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函数即可完成设置!

答案 3 :(得分:0)

我认为处理InfoWindow时的常见做法是创建一个全局窗口 并使用每个标记将其绑定到click事件,而不是为每个标记创建一个。 我用谷歌标记制作了一个简单的应用程序,这就是我使用的。希望这有帮助!

    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);
    }