2010-04-19 8 views
18

Nie wiem, dlaczego to nie działa. Nie mam żadnych błędów, ale co się dzieje, bez względu na to, który znacznik kliknę, zawsze klika ostatni znacznik. Nie wiem dlaczego, ponieważ the_marker jest ustawiony w ten sam sposób. Jak mogę rozwiązać ten problem ?:Zapętlanie znaczników za pomocą interfejsu Google Maps API v3 Problem

(aktualizowana o nowe 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

Co to jest 1201-1299 SW Washington Stunstarred, Portland, OR 97205? – BalusC

+0

@BalusC: Innowacyjna obudowa: http: // mapy.google.com/maps?f=q&source=s_q&hl=pl&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 2120,78, 0,49.79 & ll = 45.522007, -122,683811 & spn = 0,006186,0.01413 & z = 17 :) –

+0

haha, szczerze mówiąc, właśnie wrzuciłem współrzędne, aby być dobrym widokiem na miasto Portland :) –

Odpowiedz

21

masz a very common closure problem w następującej pętli:

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

Zmienne zamknięte w akcję zamknięcia taki sam pojedyncze środowisko, więc do czasu wykonywania wywołań zwrotnych click pętla zakończyła swój kurs, a zmienna x zostanie wyświetlona, ​​wskazując ostatnią pozycję.

Można go rozwiązać korzystając z jeszcze większej zamknięć przy użyciu funkcji fabrycznej:

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

To może być dość trudnym tematem, jeśli nie są zaznajomieni ze sposobem pracy zamknięć. można sprawdzić następujący artykuł Mozilla za krótkie wprowadzenie:


UPDATE:

nawiązaniu do zaktualizowanego pytanie, należy wziąć pod uwagę następujące elementy:

  • Przede wszystkim należy pamiętać, że JavaScript nie ma zasięgu bloku. Tylko funkcje mają zasięg.

  • Po przypisaniu zmiennej, która nie została wcześniej zadeklarowana za pomocą słowa kluczowego var, zostanie zadeklarowana jako zmienna globalna. Jest to często uważane za brzydką cechę (lub wadę) JavaScript, ponieważ może ukryć w milczeniu wiele błędów. Dlatego należy tego unikać. Masz dwa wystąpienia tych domyślnych zmiennych globalnych: the_marker i infowindow, i w rzeczywistości właśnie dlatego Twój program się nie udaje.

  • JavaScript ma zamknięcia. Oznacza to, że funkcje wewnętrzne mają dostęp do zmiennych i parametrów funkcji zewnętrznej. Z tego powodu będzie można uzyskać dostęp do the_marker, infowindow i map z funkcji wywołania zwrotnego metody addListener. Jednak ponieważ twoje the_marker i są traktowane jako zmienne globalne, zamknięcie nie działa.

Wszystko, co musisz zrobić, to użyć słowa kluczowego var kiedy je zadeklarować, jak w poniższym przykładzie:

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

Przepraszamy , czy mógłbyś pokazać mi mój obecny kod? Jestem trochę zdezorientowany. : \ Dzięki za całą pomoc. Musiałem go zaktualizować, aby używać jQuery i pliku XML. –

+0

@Oscar: Jasne, pozwól mi rzucić okiem ... –

+1

@Oscar: Zaktualizowano moją odpowiedź. Powinieneś po prostu zadeklarować zmienne 'the_marker' i' infowindow' ze słowem kluczowym 'var'. –

3

Oto moje podejście.

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

możesz dodać więcej ... to jest dobry kod – Amitsharma