2010-04-19 21 views
18

Non so perché questo non funzioni. Non ho errori, ma quello che succede è, non importa quale marker clicco, fa sempre clic sull'ultimo marker. Non sono sicuro del perché anche se the_marker è impostato allo stesso modo. Come posso risolvere questo problema ?:Looping di marker con l'API di Google Maps v3 Problema

(aggiornato con nuove 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

Cosa c'è 1201-1299 SW Washington Stunstarred, Portland, OR 97205? – BalusC

+0

@BalusC: Housing innovativo: 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

haha, a dire il vero, ho appena inserito le coordinate di venire per essere una buona vista della città di Portland :) –

risposta

21

Si stanno avendo a very common closure problem nel seguente ciclo:

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

variabili racchiuse in una quota di chiusura dello stesso ambiente singolo, quindi al momento dell'esecuzione delle richiamate click, il ciclo ha fatto il suo corso e la variabile x verrà lasciata puntata sull'ultima voce.

si può risolvere con ancora più chiusure, utilizzando una funzione di fabbrica:

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

Questo può essere un bel argomento difficile, se non si ha familiarità con il modo di lavoro chiusure. Si può verificare il seguente articolo di Mozilla per una breve introduzione:


UPDATE:

A seguito della domanda aggiornato, si dovrebbe considerare quanto segue:

  • Prima di tutto, tieni presente che JavaScript non ha scope di blocco. Solo le funzioni hanno scope.

  • Quando si assegna una variabile che non è stata precedentemente dichiarata con la parola chiave var, verrà dichiarata come variabile globale. Questo è spesso considerato una brutta caratteristica (o difetto) di JavaScript, in quanto può nascondere in modo silenzioso molti bug. Pertanto questo dovrebbe essere evitato. Esistono due istanze di queste variabili globali implicite: the_marker e infowindow e, di fatto, questo è il motivo per cui il programma non funziona.

  • JavaScript è stato chiuso. Ciò significa che le funzioni interne hanno accesso alle variabili e ai parametri della funzione esterna. Questo è il motivo per cui sarà possibile accedere a the_marker, infowindow e map dalla funzione di callback del metodo addListener. Tuttavia, poiché il tuo the_marker e infowindow vengono trattati come variabili globali, la chiusura non funziona.

Tutto quello che dovete fare è quello di utilizzare la parola chiave var quando vengono dichiarate, come nel seguente esempio:

$(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

Siamo spiacenti , potresti mostrarmi con il mio codice attuale? Sono un po 'confuso tutto. :\ Grazie per tutto l'aiuto. Ho dovuto aggiornarlo per usare jQuery e un file XML. –

+0

@Oscar: Certo, lasciami dare un'occhiata ... –

+1

@Oscar: aggiornata la mia risposta. Devi semplicemente dichiarare le tue variabili 'the_marker' e' infowindow' con la parola chiave 'var'. –

3

Ecco il mio approccio.

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

puoi aggiungere altro ... questo è un buon codice – Amitsharma