【问题标题】:How to link each Marker with it's own infoWindow?如何将每个标记与它自己的 infoWindow 链接?
【发布时间】:2016-09-03 21:44:21
【问题描述】:

如您所见,我正在迭代一个包含标记信息的 json 对象,如下所示:

(我也在使用信息框插件,但与问题无关)

function drawAirports() {
    var markers = [];

    if ( markers != undefined) {
        for (var i = 0; i < markers.length; i++ ) {
            markers[i].setMap(null);
        }
        markers.length = 0;
    }

    var json = [
        {"id":8585885,"airport":"airport name", "lat" : "1.3", "long" : "1.33"},
        {"id":8585886,"airport":"airport name 1", "lat" : "-1.3", "long" : "1.33"},
        {"id":8585886,"airport":"airport name 2", "lat" : "42.5000", "long" : "1.5000"},
        {"id":8585886,"airport":"airport name 3", "lat" : "24.0000", "long" : "54.0000"},
        {"id":8585886,"airport":"airport name 4", "lat" : "17.0500", "long" : "-61.8000"},
        {"id":8585886,"airport":"airport name 5", "lat" : "18.2500", "long" : "-63.1667"},
        {"id":8585886,"airport":"airport name 6", "lat" : "24.0000", "long" : "54.0000"},
        {"id":8585886,"airport":"airport name 7", "lat" : "41.0000", "long" : "20.0000"},
        {"id":8585886,"airport":"airport name 8", "lat" : "40.0000", "long" : "45.0000"},
        {"id":8585886,"airport":"airport name 9", "lat" : "12.2500", "long" : "-68.7500"},
        {"id":8585886,"airport":"airport name 10", "lat" : "-12.5000", "long" : "18.5000"},
        {"id":8585886,"airport":"airport name 11", "lat" : "35.0000", "long" : "105.0000"},
        {"id":8585886,"airport":"airport name 12", "lat" : "-90.0000", "long" : "0.0000"},
        {"id":8585886,"airport":"airport name 13", "lat" : "34.0000", "long" : "-64.0000"},
        {"id":8585886,"airport":"airport name 14", "lat" : "-14.3333", "long" : "-170.0000"},
        {"id":8585886,"airport":"airport name 15", "lat" : "47.3333", "long" : "13.3333"},
        {"id":8585886,"airport":"airport name 16", "lat" : "-27.0000", "long" : "133.0000"},
        {"id":8585886,"airport":"airport name 17", "lat" : "12.5000", "long" : "-69.9667"}
    ];

    var airports = eval(json);

    for (var i = 0; i < airports.length; i++) {

        var airport = airports[i];

        var marker = new google.maps.Marker({
            position: new google.maps.LatLng(airport.lat, airport.long),
            map: map,
            title: airport.airport,
            icon: 'img/gmaps/marker.png',
            visible: true
        });

        infobox = new InfoBox({
             content: '<h3>'+airport.airport+'</h3><a class="info" href="">Información</a><a class="bags" href="">Equipajes</a>',
             disableAutoPan: false,
             maxWidth: 150,
             pixelOffset: new google.maps.Size(-212, -150),
             zIndex: null,
             boxStyle: {
                width: "280px"
            },
            closeBoxMargin: "0",
            closeBoxURL: "img/gmaps/close.png",
            infoBoxClearance: new google.maps.Size(1, 1)
        });

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

        markers.push(marker);                       
    }
}

我的问题是每个标记都会打开最后一个(数字 17)信息窗口,

我做错了什么?

【问题讨论】:

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


    【解决方案1】:

    因此,您的问题不在于 Google Maps API 的利用率或库,而在于您使用闭包的方式。您有全局变量infobox,这很好,因为您只需要一个信息框并在打开新信息框之前关闭地图上存在的所有信息框,但是您拥有它的方式infobox 始终指向最后一个创建的信息框,即编号 17 ,最后一个位置。只需使用 Javascript 闭包并在侦听器代码中创建信息框,利用 airport 由于闭包而始终包含正确数据的事实。这应该有效:

    function drawAirports() {
      var markers = [];
      var infobox = new InfoBox({
          content: '',
          disableAutoPan: false,
          maxWidth: 150,
          pixelOffset: new google.maps.Size(-212, -150),
          zIndex: null,
          boxStyle: {
              width: "280px"
          },
          closeBoxMargin: "0",
          closeBoxURL: "img/gmaps/close.png",
          infoBoxClearance: new google.maps.Size(1, 1)
      });
    
      if (markers != undefined) {
          for (var i = 0; i < markers.length; i++) {
              markers[i].setMap(null);
          }
          markers.length = 0;
      }
    
      var json = [
          {"id": 8585885, "airport": "airport name", "lat": "1.3", "long": "1.33"},
          {"id": 8585886, "airport": "airport name 1", "lat": "-1.3", "long": "1.33"},
          {"id": 8585886, "airport": "airport name 2", "lat": "42.5000", "long": "1.5000"},
          {"id": 8585886, "airport": "airport name 3", "lat": "24.0000", "long": "54.0000"},
          {"id": 8585886, "airport": "airport name 4", "lat": "17.0500", "long": "-61.8000"},
          {"id": 8585886, "airport": "airport name 5", "lat": "18.2500", "long": "-63.1667"},
          {"id": 8585886, "airport": "airport name 6", "lat": "24.0000", "long": "54.0000"},
          {"id": 8585886, "airport": "airport name 7", "lat": "41.0000", "long": "20.0000"},
          {"id": 8585886, "airport": "airport name 8", "lat": "40.0000", "long": "45.0000"},
          {"id": 8585886, "airport": "airport name 9", "lat": "12.2500", "long": "-68.7500"},
          {"id": 8585886, "airport": "airport name 10", "lat": "-12.5000", "long": "18.5000"},
          {"id": 8585886, "airport": "airport name 11", "lat": "35.0000", "long": "105.0000"},
          {"id": 8585886, "airport": "airport name 12", "lat": "-90.0000", "long": "0.0000"},
          {"id": 8585886, "airport": "airport name 13", "lat": "34.0000", "long": "-64.0000"},
          {"id": 8585886, "airport": "airport name 14", "lat": "-14.3333", "long": "-170.0000"},
          {"id": 8585886, "airport": "airport name 15", "lat": "47.3333", "long": "13.3333"},
          {"id": 8585886, "airport": "airport name 16", "lat": "-27.0000", "long": "133.0000"},
          {"id": 8585886, "airport": "airport name 17", "lat": "12.5000", "long": "-69.9667"}
      ];
    
      var airports = eval(json);
    
      for (var i = 0; i < airports.length; i++) {
          (function (airport) {
    
              var marker = new google.maps.Marker({
                  position: new google.maps.LatLng(airport.lat, airport.long),
                  map: map,
                  title: airport.airport,
                  icon: 'img/gmaps/marker.png',
                  visible: true
              });
    
              google.maps.event.addListener(marker, 'click', function () {
                  infobox.setContent('<h3>' + airport.airport + '</h3><a class="info" href="">Información</a><a class="bags" href="">Equipajes</a>');
                  infobox.open(map, this);
              });
    
              markers.push(marker);
          })(airports[i]);
      }
    }
    

    【讨论】:

    • 如果您想了解更多关于闭包的信息:w3schools.com/js/js_function_closures.asp
    • 这可能不是你应该这样做的方式......你最好只创建一个 InfoBox 实例并使用setContent 方法来更新内容。
    • @MrUpsidown 我已经根据你的建议更新了我的答案,但我必须说还有很多其他的改进可以做。与 SO 上的大多数代码示例相同。我还在函数的范围内包含了信息框,因此不会污染全局范围。但我仍然认为,考虑到我的回答是证明错误使用范围并不是实现用户想要的最可行的方法,因此对一些细节进行投票和否决真的很琐碎。
    • 现在这是一个更好的答案。我删除了我的反对票。而且我认为这是推动人们更新/改进他们的答案的好方法;-)
    • 顺便说一句。只有一个信息框,我认为你不需要if(infobox) infobox.close(); 行,如果它的工作方式与标准信息窗口相同。
    猜你喜欢
    • 2013-06-03
    • 1970-01-01
    • 2019-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多