Примечание: Я использую v3 Google Maps API
Я пытаюсь добавить информационное окно к каждому маркеру, я поставил карту. В настоящее время я делаю это со следующим кодом:
for (var i in tracks[racer_id].data.points) {
values = tracks[racer_id].data.points[i];
point = new google.maps.LatLng(values.lat, values.lng);
if (values.qst) {
var marker = new google.maps.Marker({map: map, position: point, clickable: true});
tracks[racer_id].markers[i] = marker;
var info = new google.maps.InfoWindow({
content: '<b>Speed:</b> ' + values.inst + ' knots'
});
tracks[racer_id].info[i] = info;
google.maps.event.addListener(marker, 'click', function() {
info.open(map, marker);
});
}
track_coordinates.push(point);
bd.extend(point);
}
Проблема состоит в том, когда я нажимаю на маркер, она просто отображает информационное окно для последнего добавленного маркера. Также только, чтобы быть ясным информационное окно появляется рядом с последним маркером не маркер, на который нажимают. Я предположил бы, что моя проблема находится в addListener части, но не является postitive. Какие-либо идеи?
У вас очень распространенная проблема с закрытием в цикле for in
:
Переменные, заключенные в замыкание, используют одну и ту же единую среду, поэтому к моменту выполнения обратного вызова click
из addListener
будет вызывается, цикл завершится, а переменная info
останется указывающей на последний объект, который оказывается последнее созданное InfoWindow
.
В этом случае один из простых способов решить эту проблему - добавить в объект Marker
объект InfoWindow
:
var marker = new google.maps.Marker({map: map, position: point, clickable: true});
marker.info = new google.maps.InfoWindow({
content: '<b>Speed:</b> ' + values.inst + ' knots'
});
google.maps.event.addListener(marker, 'click', function() {
marker.info.open(map, marker);
});
Это может быть довольно сложной темой, если вы не знакомы с тем, как работают замыкания. Вы можете ознакомиться со следующей статьей Mozilla для краткого введения:
Также имейте в виду, что API v3 позволяет использовать несколько InfoWindow
на карте.Если вы хотите, чтобы одновременно отображалось только одно InfoWindow
, вам следует вместо этого использовать один объект InfoWindow
, а затем открывать его и изменять его содержимое при каждом щелчке по маркеру ( Источник ).
Попробуйте следующее:
for (var i in tracks[racer_id].data.points) {
values = tracks[racer_id].data.points[i];
point = new google.maps.LatLng(values.lat, values.lng);
if (values.qst) {
var marker = new google.maps.Marker({map: map, position: point, clickable: true});
tracks[racer_id].markers[i] = marker;
var info = new google.maps.InfoWindow({
content: '<b>Speed:</b> ' + values.inst + ' knots'
});
tracks[racer_id].info[i] = info;
google.maps.event.addListener(tracks[racer_id].markers[i], 'click', function() {
tracks[racer_id].info[i].open(map, tracks[racer_id].markers[i]);
});
}
track_coordinates.push(point);
bd.extend(point);
}
Привет всем. Я не знаю, является ли это оптимальным решением, но я решил опубликовать его здесь, чтобы надеяться помочь людям в будущем. Пожалуйста, прокомментируйте, если вы видите что-то, что должно быть изменено.
Мой цикл for теперь выглядит так:
for (var i in tracks[racer_id].data.points) {
values = tracks[racer_id].data.points[i];
point = new google.maps.LatLng(values.lat, values.lng);
if (values.qst) {
tracks[racer_id].markers[i] = add_marker(racer_id, point, '<b>Speed:</b> ' + values.inst + ' knots<br /><b>Invalid:</b> <input type="button" value="Yes" /> <input type="button" value="No" />');
}
track_coordinates.push(point);
bd.extend(point);
}
А add_marker
определяется так:
var info_window = new google.maps.InfoWindow({content: ''});
function add_marker(racer_id, point, note) {
var marker = new google.maps.Marker({map: map, position: point, clickable: true});
marker.note = note;
google.maps.event.addListener(marker, 'click', function() {
info_window.content = marker.note;
info_window.open(map, marker);
});
return marker;
}
Вы можете использовать info_window.close(), чтобы выключить информационное окно в любое время. Надеюсь, это кому-нибудь поможет.