2010-04-19 22 views
18

No estoy seguro de por qué esto no funciona. No tengo ningún error, pero lo que sucede es que no importa en qué marcador haga clic, siempre hace clic en el último marcador. No estoy seguro de por qué, porque the_marker está configurado de la misma manera. ¿Cómo puedo solucionar esto ?:Looping through Markers with Google Maps API v3 Problema

(actualizado con nueva 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); 
      }); 
     }); 
    }); 
}); 
+0

¿Qué hay en 1201-1299 SW Washington Stunstarred, Portland, OR 97205? – BalusC

+0

@BalusC: Vivienda innovadora: http: // maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=45.522015,-122.683811&sll=37.0625,-95.677068&sspn=56.506174,115.751953&ie=UTF8&layer=c&cbll=45.521974,-122.683763&panoid=rJ-wI-KGVczmS-e5OayQSQ&cbp = 12,220.78,, 0,4.79 & ll = 45.522007, -122.683811 & spn = 0.006186,0.01413 & z = 17 :) –

+0

jaja, para ser honesto, simplemente eché las coordenadas para ser una buena vista de la ciudad de Portland :) –

Respuesta

21

Usted está teniendo a very common closure problem en el siguiente bucle:

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

variables encerradas en una cuota de cierre de la misma entorno único, por lo que cuando se ejecutan las devoluciones de llamada click, el ciclo ha seguido su curso y la variable x se mantendrá hacia la última entrada.

se puede resolver con aún más cierres, utilizando una fábrica de función:

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

Este puede ser un tema bastante complicado, si no está familiarizado con la forma cierres de trabajo. Usted puede comprobar hacia fuera el siguiente artículo de Mozilla para una breve introducción:


ACTUALIZACIÓN:

En relación con la cuestión actualizado, debería considerar lo siguiente:

  • En primer lugar, tenga en cuenta que JavaScript no tiene alcance de bloque. Solo las funciones tienen alcance.

  • Cuando asigna una variable que no se declaró previamente con la palabra clave var, se declarará como una variable global. Esto a menudo se considera una característica fea (o defecto) de JavaScript, ya que puede ocultar muchos errores en silencio. Por lo tanto, esto debe evitarse. Tiene dos instancias de estas variables globales implícitas: the_marker y infowindow, y de hecho, esta es la razón por la que su programa está fallando.

  • JavaScript tiene cierres. Esto significa que las funciones internas tienen acceso a las variables y parámetros de la función externa. Es por eso que podrá acceder al the_marker, infowindow y map desde la función de devolución de llamada del método addListener. Sin embargo, debido a que su the_marker y infowindow se están tratando como variables globales, el cierre no funciona.

Todo lo que necesita hacer es utilizar la palabra clave var al declararlas, como en el siguiente ejemplo:

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

Lo siento , ¿podría mostrarme con mi código actual? Estoy un poco confundido es todo. :\ Gracias por toda la ayuda. Tuve que actualizarlo para usar jQuery y un archivo XML. –

+0

@Oscar: Claro, déjame echar un vistazo ... –

+1

@Oscar: He actualizado mi respuesta. Simplemente debe declarar sus variables 'the_marker' e' infowindow' con la palabra clave 'var'. –

3

Aquí está mi enfoque.

for(x in locations){ 
    var name = locations[x][0]; 
    var latlng = locations[x][3]; 
    addMarker(map, name, latlng); 
} 

function addMarker(map, name, latlng){ 
    var infoWin = new google.maps.InfoWindow({content: name}); 
    var marker = new google.maps.Marker({ 
     map: map, 
     position: latlng, 
     title: name 
    }); 
    google.maps.event.addListener(marker, 'click', function(){ 
     infoWin.open(map, marker); 
    }); 
} 
+0

puede agregar más ... este es un buen código – Amitsharma