簡體   English   中英

單擊標記時,Google Maps v3將打開最后一個infoWindow

[英]Google Maps v3 opens the last infoWindow when a marker is clicked

我所有的標記都有一個共享的infoWindow 如果我使用jquery的$().each(function(){}) ,它會很好地工作,但是如果我將其更改為JavaScrips的for或while循環本機,則無法正常工作。

每當我單擊一個標記時,它將打開最后一個填充的標記的infoWindow ,而不是單擊的標記的infoWindow

這有效:

$(stores).each(function() {

   var storeId = $(this).attr('storeId');
   var address = $(this).attr('rawAddress');
   var city = $(this).attr('city');
   var state = $(this).attr('state');
   var zip = $(this).attr('zip');
   var lat = $(this).attr('lat');
   var lng = $(this).attr('lng');
   var distance = $(this).attr('distance');

   //create marker
   var point = new google.maps.LatLng(lat, lng);

   var marker = new google.maps.Marker({ position: point
     , map: InStorePickup.map
     , title: city + ' #' + storeId
   });

   //create infowindow content
   var infoWindowContent = '<div style="font-size: 8pt;">'
     + '<strong>' + city + ' #' + storeId + '</strong> (' + parseFloat(distance).toFixed(2) + 'mi)<br />'
     + address + '<br />' + city + ', ' + state + ' ' + zip
     + '</div>';

   google.maps.event.addListener(marker, 'click', function() {
     InStorePickup.openInfoWindow(marker, infoWindowContent);
   });

   bounds.extend(point);
 });

但這不起作用:

for (var i = 0; i < 3; i++) {
    var store = stores[i];

    var storeId = $(store).attr('storeId');
    var address = $(store).attr('rawAddress');
    var city = $(store).attr('city');
    var state = $(store).attr('state');
    var zip = $(store).attr('zip');
    var lat = $(store).attr('lat');
    var lng = $(store).attr('lng');
    var distance = $(this).attr('distance');

    //create marker
    var point = new google.maps.LatLng(lat, lng);

    var marker = new google.maps.Marker({ position: point
                  , map: InStorePickup.map
                  , title: city + ' #' + storeId
    });

    //create infowindow content
    var infoWindowContent = '<div style="font-size: 8pt;">'
                   + '<strong>' + city + ' #' + storeId + '</strong> (' + parseFloat(distance).toFixed(2) + 'mi)<br />'
                   + address + '<br />' + city + ', ' + state + ' ' + zip
                   + '</div>';

    google.maps.event.addListener(marker, 'click', function() {
        InStorePickup.openInfoWindow(marker, infoWindowContent);
    });

    bounds.extend(point);
}

有什么想法嗎?

for循環中,您將遇到一個非常常見的關閉問題 順便說一句, 昨天剛剛就這個話題回答了類似的問題 ,您可能想看看。

閉包中包含的變量共享相同的單一環境,因此,在調用click回調時,循環將運行其過程,並且infoWindowContent變量將指向其最后分配的值。

解決此問題的一種方法是使用函數工廠使用更多閉包:

function makeInfoWindowListener (pMarker, pContent) {  
  return function() {
    InStorePickup.openInfoWindow(pMarker, pContent);
  };  
}


// ...

for (var i = 0; i < 3; i++) {

  // ...

  var infoWindowContent = '<div style="font-size: 8pt;">' + city + '...</div>';

  google.maps.event.addListener(
    marker, 
    'click', 
    makeInfoWindowListener(marker, infoWindowContent)
  );
}

如果您不熟悉閉包的工作原理,那么這可能是一個棘手的話題。 您可能有興趣查看以下文章以進行簡要介紹:


更新:

之所以使用jQuery示例,是因為傳遞給each()方法的函數將每次迭代都包含在自己的范圍內。 實際上,您可以在普通的JavaScript示例中執行相同的操作:

for (var i = 0; i < 3; i++) {

  // each iteration will now have its own scope
  (function () {

     var infoWindowContent = '<div style="font-size: 8pt;">' + city + '...</div>';

     google.maps.event.addListener(marker, 'click', function() {
       InStorePickup.openInfoWindow(marker, infoWindowContent);
     });

  })();
}

第二次更新:

請注意,也可以使用匿名函數將第一個示例重寫如下:

for (var i = 0; i < 3; i++) {

  // ...

  var infoWindowContent = '<div style="font-size: 8pt;">' + city + '...</div>';

  google.maps.event.addListener(marker, 'click', (function (pMarker, pContent) {  
    return function() {
      InStorePickup.openInfoWindow(pMarker, pContent);
    };  
  })(marker, infoWindowContent));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM