2010-04-19 58 views
18

我不知道爲什麼這不起作用。我沒有任何錯誤,但會發生什麼,無論點擊什麼標記,它總是點擊最後一個標記。我不知道爲什麼,因爲the_marker設置相同的方式。我怎樣才能解決這個問題?:使用谷歌地圖API v3通過標記進行循環問題

(更新了新的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

什麼是在1201至1299年華盛頓西南Stunstarred,波特蘭,俄勒岡97205? – BalusC 2010-04-19 20:17:16

+0

@BalusC:創新的住房:http://地圖。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 :) – 2010-04-19 20:25:36

+0

哈哈,說實話,我只是扔進來座標來成爲波特蘭市的一個很好的看法:) – 2010-04-19 21:39:37

回答

21

你有下面的循環中a very common closure problem

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變量將被指向最後一個條目。

你可以用更倒閉解決它,使用函數工廠:

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的文章作一簡要介紹:


UPDATE:

而且更新後的問題,您應該考慮以下幾點:

  • 首先,請記住,JavaScript沒有塊範圍。只有功能纔有範圍。

  • 當您將一個以前未用var關鍵字聲明的變量賦值時,它將被聲明爲全局變量。這通常被認爲是JavaScript的一個醜陋特徵(或缺陷),因爲它可以默默地隱藏許多錯誤。因此應該避免這種情況。你有兩個隱含的全局變量的實例:the_markerinfowindow,實際上,這就是你的程序失敗的原因。

  • JavaScript已關閉。這意味着內部函數可以訪問外部函數的變量和參數。這就是爲什麼您可以通過addListener方法的回調函數訪問the_markerinfowindowmap。但是,因爲您的the_markerinfowindow正被視爲全局變量,所以閉包不起作用。

所有你需要做的是,當你聲明它們,如下面的例子使用var關鍵字:

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

對不起,你能告訴我現在的代碼嗎?我有點困惑。 :\感謝所有的幫助。我不得不更新它來使用jQuery和一個XML文件。 – 2010-04-19 23:27:10

+0

@Oscar:當然,讓我看看... – 2010-04-19 23:30:56

+1

@Oscar:更新了我的答案。你應該簡單地用'var'關鍵字聲明'the_marker'和'infowindow'變量。 – 2010-04-19 23:53:34

3

這裏是我的做法。

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

可以添加更多...這是很好的代碼 – Amitsharma 2014-02-21 14:28:10