2010-04-19 50 views
18

Tôi không chắc chắn tại sao tính năng này không hoạt động. Tôi không có bất kỳ lỗi nào, nhưng điều xảy ra là, bất kể điểm đánh dấu nào tôi nhấp vào, nó luôn nhấp vào điểm đánh dấu cuối cùng. Im không chắc chắn lý do tại sao mặc dù bởi vì the_marker được thiết lập theo cùng một cách. Làm thế nào tôi có thể sửa lỗi này ?:Lặp qua các điểm đánh dấu bằng API Google Maps v3 Sự cố

(Cập nhật với mới 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

Có gì ở 1201-1299 SW Washington Stunstarred, Portland, OR 97205? – BalusC

+0

@BalusC: Nhà ở sáng tạo: http: // maps.google.com/maps?f=q&source=s_q&hl=vi&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, thành thật mà nói, tôi chỉ ném vào tọa độ để có một cái nhìn tốt về Thành phố Portland :) –

Trả lời

21

Bạn đang có a very common closure problem trong vòng lặp sau:

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

biến kèm theo trong một phần đóng cùng môi trường duy nhất, do đó, vào thời điểm các cuộc gọi lại click được thực hiện, vòng lặp đã chạy khóa học của nó và biến số x sẽ được trỏ sang mục nhập cuối cùng.

Bạn có thể giải quyết nó với thậm chí nhiều hơn đóng cửa, sử dụng một nhà máy chức năng:

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

này có thể khá một chủ đề phức tạp, nếu bạn không quen thuộc với cách đóng cửa làm việc. Bạn có thể kiểm tra bài viết Mozilla sau cho một giới thiệu ngắn gọn:


UPDATE:

Tiếp tục với câu hỏi được cập nhật, bạn nên cân nhắc những điều sau đây:

  • Trước hết, hãy nhớ rằng JavaScript không có phạm vi khối. Chỉ các hàm có phạm vi.

  • Khi bạn chỉ định biến chưa được khai báo trước đó với từ khóa var, từ khóa đó sẽ được khai báo dưới dạng biến toàn cục. Điều này thường được coi là một tính năng xấu xí (hoặc lỗ hổng) của JavaScript, vì nó có thể ẩn âm thầm nhiều lỗi. Do đó điều này nên tránh. Bạn có hai trường hợp của các biến toàn cục được ngụ ý này: the_markerinfowindow và trên thực tế, đây là lý do tại sao chương trình của bạn bị lỗi.

  • JavaScript đã đóng. Điều này có nghĩa rằng các hàm bên trong có quyền truy cập vào các biến và tham số của hàm bên ngoài. Đây là lý do tại sao bạn có thể truy cập the_marker, infowindowmap từ chức năng gọi lại của phương thức addListener. Tuy nhiên, vì các số the_markerinfowindow của bạn đang được coi là biến toàn cầu, việc đóng không hoạt động.

Tất cả bạn cần làm là sử dụng các từ khóa var khi bạn khai báo họ, như trong ví dụ sau:

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

Xin lỗi , bạn có thể cho tôi xem mã hiện tại của tôi không? Im một chút bối rối là tất cả. :\ Cảm ơn vì sự giúp đỡ. Tôi đã phải cập nhật nó để sử dụng jQuery và một tệp XML. –

+0

@ OSC: Chắc chắn, hãy để tôi xem ... –

+1

@Oscar: Cập nhật câu trả lời của tôi. Bạn chỉ cần khai báo các biến 'the_marker' và' infowindow' bằng từ khóa 'var'. –

3

Đây là cách tiếp cận của tôi.

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

bạn có thể thêm nhiều hơn nữa ... đây là mã hay không – Amitsharma

Các vấn đề liên quan