当点击标记时,Google地图v3会打开最后一个infoWindow [英] Google Maps v3 opens the last infoWindow when a marker is clicked

查看:127
本文介绍了当点击标记时,Google地图v3会打开最后一个infoWindow的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个共享的 infoWindow 所有我的标记。如果我使用jquery的 $()。每个(function(){}),但是如果我把它改为JavaScrips的原生for或while循环,预期。



每当我点击某个标记时,它会打开最后一个填充标记的 infoWindow ,而不是点击的标记 infoWindow



这样工作:

 code> $(stores).each(function(){

var storeId = $(this).attr('storeId');
var address = .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 ');
var distance = $(this).attr('distance');

//创建标记
var point = new google.maps.LatLng(lat, lng);

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

//创建infowindow内容
var infoWindowContent ='< div style =font-size:8pt;>'
+'< ; strong>'+ city +'#'+ storeId +'< / strong> ('+ parseFloat(distance).toFixed(2)+'mi)< br />'
+ address +'>'+ 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距离= $(this).attr('distance');

//创建标记
var point = new google.maps.LatLng(lat,lng);

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

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

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

bounds.extend(point);任何想法?


h2_lin>解决方案

您将拥有循环中的一个非常常见的闭包问题。顺便说一下,我昨天就这个话题回答了类似的问题



封闭在一个闭包中的变量共享同一个单一环境,所以到点击 callback被调用,循环将运行它的路线,并且 infoWindowContent 变量将指向它分配给的最后一个值。



一个解决方法是使用更多的闭包,使用函数工厂:

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

这可能是一个相当棘手的话题,如果你不熟悉如何封闭工作。您可能有兴趣查看以下文章以获取简要说明:








UPDATE:



jQuery示例工作原因是因为您传递的函数到 each()方法将每个迭代包含在其自身的作用域中。你可以在纯JavaScript示例中做同样的事情:

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

//每个迭代现在都有自己的范围
(function(){

var infoWindowContent ='< div style = :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));
}


I have a shared infoWindow for all my markers. It works good if I use jquery's $().each(function(){}), but if I change it to JavaScrips's native for or while loop, it's not working as expected.

Whenever I click a marker, it will open the last populated marker's infoWindow, instead of the clicked marker's infoWindow.

This works:

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

But this does not work:

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

Any thoughts?

解决方案

You would be having a very common closure problem in the for loop. Incidentally I have answered a similar question on this topic just yesterday, which you may want to check out.

Variables enclosed in a closure share the same single environment, so by the time the click callback is called, the loop will have run its course and the infoWindowContent variable will be left pointing to the last value it was assigned to.

One way to solve this is with more closures, using a function factory:

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

This can be quite a tricky topic, if you are not familiar with how closures work. You may be interested in checking out the following article for a brief introduction:


UPDATE:

The reason why the jQuery example works, is because the function you pass to the each() method encloses each iteration in its own scope. You could practically do the same thing in your plain JavaScript example:

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

  })();
}


2nd UPDATE:

Note that the first example can also be rewritten as follows, using an anonymous function:

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

这篇关于当点击标记时,Google地图v3会打开最后一个infoWindow的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆