使用 Google Maps API v3 问题遍历标记 [英] Looping through Markers with Google Maps API v3 Problem

查看:22
本文介绍了使用 Google Maps API v3 问题遍历标记的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不确定为什么这不起作用.我没有任何错误,但发生的情况是,无论我点击什么标记,它总是点击最后一个标记.我不知道为什么,因为 the_marker 的设置方式相同.我该如何解决这个问题?:

I'm not sure why this isn't working. I don't have any errors, but what happens is, no matter what marker I click on, it always clicks the last marker. Im not sure why though because the_marker is set up the same way. How can I fix this?:

(使用新的 jQuery + XML 更新)

(Updated with new jQuery + XML)

$(function(){
    var latlng = new google.maps.LatLng(45.522015,-122.683811);
    var settings = {
        zoom: 15,
        center: latlng,
        disableDefaultUI:true,
        mapTypeId: google.maps.MapTypeId.SATELLITE
    };
    var map = new google.maps.Map(document.getElementById("map_canvas"), settings);

    $.get('mapdata.xml',{},function(xml){
        $('location',xml).each(function(i){
            the_marker = new google.maps.Marker({
                title:$(this).find('name').text(),
                map:map,
                clickable:true,
                position:new google.maps.LatLng(
                    parseFloat($(this).find('lat').text()),
                    parseFloat($(this).find('lng').text())
                )
            });
            infowindow = new google.maps.InfoWindow({
                content: $(this).find('description').text()
            });
            new google.maps.event.addListener(the_marker, 'click', function() {
                infowindow.open(map,the_marker);
            });
        });
    });
});

推荐答案

您有 以下循环中非常常见的闭包问题:

for(x in locations){
   console.log(x);
   infowindow[x] = new google.maps.InfoWindow({content: x});
   marker[x] = new google.maps.Marker({title:locations[x][0],map:map,position:locations[x][2]});
   google.maps.event.addListener(marker[x], 'click', function() {infowindow[x].open(map,marker[x]);});
}

封闭在闭包中的变量共享同一个环境,所以当 click 回调被执行时,循环已经运行,x 变量将是左指向最后一个条目.

Variables enclosed in a closure share the same single environment, so by the time the click callbacks are executed, the loop has run its course and the x variable will be left pointing to the last entry.

你可以用更多的闭包来解决它,使用函数工厂:

You can solve it with even more closures, using a function factory:

function makeInfoWindowEvent(map, infowindow, marker) {  
   return function() {  
      infowindow.open(map, marker);
   };  
} 

for(x in locations){
   infowindow[x] = new google.maps.InfoWindow({content: x});

   marker[x] = new google.maps.Marker({title: locations[x][0],
                                       map: map, 
                                       position: locations[x][3]});

   google.maps.event.addListener(marker[x], 'click', 
                                 makeInfoWindowEvent(map, infowindow[x], marker[x]);
}

如果您不熟悉闭包的工作原理,这可能是一个非常棘手的话题.您可以查看以下 Mozilla 文章以进行简要介绍:

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

更新:

对于更新后的问题,您应该考虑以下几点:

Further to the updated question, you should consider the following:

  • 首先,请记住 JavaScript 没有块作用域.只有函数有作用域.

  • First of all, keep in mind that JavaScript does not have block scope. Only functions have scope.

当您分配一个先前未使用 var 关键字声明的变量时,它将被声明为全局变量.这通常被认为是 JavaScript 的一个丑陋的特性(或缺陷),因为它可以默默地隐藏许多错误.因此应该避免这种情况.您有这些隐含全局变量的两个实例:the_markerinfowindow,事实上,这就是您的程序失败的原因.

When you assign a variable that was not previously declared with the var keyword, it will be declared as a global variable. This is often considered an ugly feature (or flaw) of JavaScript, as it can silently hide many bugs. Therefore this should be avoided. You have two instances of these implied global variables: the_marker and infowindow, and in fact, this is why your program is failing.

JavaScript 有闭包.这意味着内部函数可以访问外部函数的变量和参数.这就是为什么您将能够从 addListener 方法的回调函数访问 the_markerinfowindowmap.但是,由于您的 the_markerinfowindow 被视为全局变量,因此闭包不起作用.

JavaScript has closures. This means that inner functions have access to the variables and parameters of the outer function. This is why you will be able to access the_marker, infowindow and map from the callback function of the addListener method. However, because your the_marker and infowindow are being treated as global variables, the closure is not working.

您需要做的就是在声明它们时使用 var 关键字,如下例所示:

All you need to do is to use the var keyword when you declare them, as in the following example:

$(function() {
   var latlng = new google.maps.LatLng(45.522015,-122.683811);

   var settings = {
      zoom: 15,
      center: latlng,
      disableDefaultUI: true,
      mapTypeId: google.maps.MapTypeId.SATELLITE
   };

   var map = new google.maps.Map(document.getElementById("map_canvas"), settings);

   $.get('mapdata.xml', {}, function(xml) {
      $('location', xml).each(function(i) {

         var the_marker = new google.maps.Marker({
            title: $(this).find('name').text(),
            map: map,
            clickable: true,
            position: new google.maps.LatLng(
               parseFloat($(this).find('lat').text()),
               parseFloat($(this).find('lng').text())
            )
         });

         var infowindow = new google.maps.InfoWindow({
            content: $(this).find('description').text();
         });

         new google.maps.event.addListener(the_marker, 'click', function() {
            infowindow.open(map, the_marker);
         });
      });
   });
});

这篇关于使用 Google Maps API v3 问题遍历标记的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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