2011-08-12 49 views
33

Tôi hiện đang sử dụng mã sau để đặt nhiều điểm đánh dấu trên Google Map bằng API của họ.Thêm nhiều điểm đánh dấu với infowindows (API Google Maps)

Sự cố tôi gặp phải là với nhiều thông tin không hoạt động (chỉ hiển thị ảnh cuối cùng).

Có vô số câu hỏi như tôi ở đây trên SO. Trên thực tế làm cho điều đó một shitload câu hỏi :-)

Chỉ cần một ví dụ: Trying to bind multiple InfoWindows to multiple Markers on a Google Map and failing

Giải pháp cho vấn đề của tôi là kinda dễ dàng: chỉ cần kèm người nghe nhấp chuột vào một chức năng (vô danh).

Tuy nhiên những gì tôi không hiểu là lý do giải pháp của tôi không hoạt động (lưu các điểm đánh dấu và infowindows trong mảng thay vì chỉ một biến).

var markers = []; 
    var infowindows = []; 

    // add shops or malls 
    for (var key in data.markers) { 
     if (data.markers.hasOwnProperty(key)) { 
     infowindows[key] = new google.maps.InfoWindow({ 
      content: data.markers[key].infowindow 
     }); 

     markers[key] = new google.maps.Marker({ 
       position: new google.maps.LatLng(data.markers[key].location.lat, data.markers[key].location.lng), 
       map: map, 
       flat: true, 
       title: data.markers[key].name, 
       draggable: false 
     }); 
     var iconFile = 'http://maps.google.com/mapfiles/ms/icons/'+marker_color+'-dot.png'; 
     markers[key].setIcon(iconFile); 

     google.maps.event.addListener(markers[key], 'click', function() { 
      infowindows[key].open(map, markers[key]); 
     }); 
     } 
    } 

Vì vậy, tôi không biết giải pháp làm cách nào để làm việc với một số chức năng kèm theo người nghe (mặc dù nó hoạt động, chưa thử nghiệm nhưng sẽ), nhưng tôi muốn biết lý do tại sao nó sẽ không hoạt động nếu tôi thêm các dấu và infowindows để mảng thay thế.

Trả lời

62

Javascript có cấu trúc ngôn ngữ được gọi là "đóng cửa". Các đóng là các hàm (chẳng hạn như hàm() {} mà bạn khai báo ở trên để xử lý với trình nghe nhấp chuột) để nắm bắt các tham chiếu đến các biến bên ngoài.

Có rất nhiều nguồn lực mà giải thích cho họ tốt hơn tôi có thể, mà tôi đề nghị bạn tham khảo ý kiến, nhưng đây là nỗ lực hết sức mình:

Trong khối này ở đây:

google.maps.event.addListener(markers[key], 'click', function() { 
     infowindows[key].open(map, markers[key]); 
    }); 

Bởi vì "chìa khóa" là đã được định nghĩa là một biến bên ngoài, hàm sẽ nắm bắt một tham chiếu đến biến đó. Vì vậy, nơi bạn mong đợi:

infowindows["helloworld"] 

Javascript sẽ thay giải thích điều này như sau:

infowindows[reference to key] 

Khi bạn bấm vào một dấu hiệu, nó nhìn lên "tài liệu tham khảo để chìa khóa" để xem những gì giá trị hiện tại của Điều quan trọng là . Bởi vì điều này có thể sẽ không xảy ra cho đến khi vòng lặp của bạn kết thúc, khóa sẽ bằng bất kỳ khóa cuối cùng nào trong đối tượng data.markers của bạn. Và nó sẽ bằng với giá trị đó cho người nghe nhấp vào MỌI bạn đã thêm.

Giải pháp, như bạn chỉ ra, là bao bọc điều này trong một hàm ẩn danh để nhận Javascript để đánh giá giá trị của "khóa" tại thời điểm người nghe nhấp được thêm vào.

google.maps.event.addListener(markers[key], 'click', function(innerKey) { 
     return function() { 
      infowindows[innerKey].open(map, markers[innerKey]); 
     } 
    }(key)); 
19

Có một cách đơn giản hơn một chút để thực hiện việc này. bạn có thể thêm thuộc tính tùy chỉnh vào điểm đánh dấu của bạn (chỉ mục của cửa sổ thông tin) và tham chiếu đến nó trong hàm gọi lại. Ví dụ bên dưới:

markers = Array(); 
    infoWindows = Array(); 

    for(var i in earthquakes) 
    { 
     var location = new google.maps.LatLng(earthquakes[i].geolat, earthquakes[i].geolong); 
     var marker = new google.maps.Marker({ 
      position : location, 
      map : map, 
      animation : google.maps.Animation.DROP, 
      infoWindowIndex : i //<---Thats the extra attribute 
     }); 
     var content = "<h3>" + earthquakes[i].title + "<h3>" + 
       "<a data-ajax='false' target='_blank' href='" + earthquakes[i].link + "'>Link to shakemap.</a>"; 
     var infoWindow = new google.maps.InfoWindow({ 
      content : content 
     }); 

     google.maps.event.addListener(marker, 'click', 
      function(event) 
      { 
       map.panTo(event.latLng); 
       map.setZoom(5); 
       infoWindows[this.infoWindowIndex].open(map, this); 
      } 
     ); 

     infoWindows.push(infoWindow); 
     markers.push(marker); 
    } 
+0

Tôi đang cố gắng theo cách này, nhưng tôi có một cảnh báo jshint "Đừng làm cho chức năng trong một vòng lặp". Nếu tôi đưa người nghe ra ngoài vòng lặp, tôi nhận được lỗi "đánh dấu được sử dụng ngoài phạm vi". Làm thế nào tôi có thể tránh nó? – aitor

8

This một giải thích khá tốt với giải pháp với trang demo.

This là trang demo.

+0

Xin lỗi cả hai bản demo đều không khả dụng. – aaa

54

Điều này phù hợp với tôi!Chỉ cần thêm một thuộc tính mới cho đối tượng điểm đánh dấu, thuộc tính này chứa đối tượng infowindow.

var mytext = 'Infowindow contents in HTML' 
var myinfowindow = new google.maps.InfoWindow({ 
    content: mytext 
}); 

var marker = new google.maps.Marker({ 
    position: mypos, 
    map: mymap, 
    icon: myicon, 
    title: mytitle, 
    infowindow: myinfowindow 
}); 

google.maps.event.addListener(marker, 'click', function() { 
     this.infowindow.open(map, this); 

}); 
+4

Điều này không trả lời được câu hỏi ban đầu chút nào! Nó chỉ hiển thị ví dụ từ tham chiếu API Google Maps với cửa sổ ONE thông tin. Xin lỗi, nhưng câu trả lời này không nên ở đây. – Zordid

+0

cách dọn dẹp và điều này đã trả lời những gì tôi đang tìm kiếm. Cảm ơn bạn! –

1

tôi sẽ sử dụng đóng cửa:

(function(infowindow, marker){google.maps.event.addListener(marker, 'click', function() { 
    infowindow.open(map, marker); 
});})(infowindow, marker) 
2
function addMarker(Latlng){ 
     marker = new google.maps.Marker({ 
      position: Latlng, 
      icon:"myicon.jpg", 
      map: map, 
      animation: google.maps.Animation.DROP, 
      title:"My tooltip" 
     }); 

     //add marker 
     marker.setMap(map); 

     contentString = "<h1>Hello World</h1>"; 

     marker.infowindow = new google.maps.InfoWindow({ 
      content: contentString 
     }); 

     //add click event 
     google.maps.event.addListener(marker, 'click', function(){ 
      this.infowindow.open(map,this); 
     }); 
    } 

    addMarker(some_lat_lang_value); 
0
var infowindow = null; 
infowindow = new google.maps.InfoWindow({ 
    content: "loading..." 
}); 
for (i = 0; i < data.dbreturn.length; i++) { 
    var latilongi = data.dbreturn[i].mapa.split(','); 
    var mapinha = {lat: parseFloat(latilongi['0']), lng:  parseFloat(latilongi['1'])}; 
    var marker = new google.maps.Marker({ 
    position: mapinha, 
    html: '<div id="content"><h5 id="firstHeading"  class="firstHeading">'+data.dbreturn[i].nome+'</h5></div>' 
}); 

google.maps.event.addListener(marker, "click", function() { 
    infowindow.setContent(this.html); 
    infowindow.open(map, this); 
}); 
} 
+1

Chào mừng bạn đến với Stack Overflow! Mặc dù mã này có thể trả lời câu hỏi, cung cấp ngữ cảnh bổ sung về lý do và/hoặc cách mã này trả lời câu hỏi cải thiện giá trị lâu dài của nó. – Ajean

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