Multiple InfoWindow
Давненько я не писал о гуглокартах. Но это скорее потому что мой проект для BetterPlace закончился фэйлом, сайт в продакшн не пошел, хотя он и был для внутреннего пользования. Единственное что стоящее осталось от этого проекта это Google Map API v3 Marker Manager, который я сегодня по случаю обновил.
Но поговорить я хотел не о картах, и не о маркерах а о InfoWindow. Забавно то что на всех картах и во всех примерах InfoWindow всегда один, при нажатии на маркер он просто меняет якорь (маркер) и текст. Никто и никогда не подозревал, что люди хотят сравнить два или больше маркера (я говорю маркера потому что без дополнительного кода google.maps.InfoWindow цепляется только к google.maps.Marker) по параметрам открыв их InfoWindow.
Итак задача: открывать для каждого маркера свой InfoWindow. На самом деле может показаться что все очень просто:
var map = new google.maps.Map(document.getElementById("map1"), {
zoom: 5,
center: new google.maps.LatLng(50.440951, 30.527181),
mapTypeId: google.maps.MapTypeId.HYBRID
});
var marker = new google.maps.Marker({
map: map,
position : new google.maps.LatLng(50.440951, 30.527181),
draggable : false
});
google.maps.event.addListener(marker, "click", function(e){
map.setCenter(this.getPosition());
new google.maps.InfoWindow({
content: this.getPosition().toString()
}).open(map, this);
});
Но нет, таким способом при каждом клике на маркер будет открываться новое InfoWindow и они будут наслаиваться. Значит надо иметь ссылки на все объекты InfoWindow.
В этом примере я уже использую MarkerManager, с ним как-то удобнее ;)
var myMarkerManager = new MarkerManager(
new google.maps.Map(document.getElementById("map2"), {
zoom: 5,
center: new google.maps.LatLng(50, 27),
mapTypeId: google.maps.MapTypeId.HYBRID
})
);
myMarkerManager.createMarker(new google.maps.LatLng(50.440951, 30.527181));
myMarkerManager.createMarker(new google.maps.LatLng(49.836944, 24.005000));
var windows = [];
function createInfoWindow(marker){
var window = new google.maps.InfoWindow({
content: marker.getPosition().toString()
})
google.maps.event.addListener(window, "closeclick", function(e){
windows.splice(MarkerManager.prototype.inArray(marker, windows), 1);
});
window.open(myMarkerManager.map, marker);
windows.push(window);
}
for (var i in myMarkerManager.markers){
google.maps.event.addListener(myMarkerManager.markers[i], "click", function(e){
myMarkerManager.map.setCenter(this.getPosition());
for (var i=0, length=windows.length; i<length; i++){
if (windows[i].getContent()==this.getPosition().toString()) {
return;
}
}
createInfoWindow(this);
})
}
Но и этот способ не айс. Смотрите что происходит: нужно иметь список всех InfoWindow, но никакого метода для их получения не существует. Я очень надеялся найти что-то вроде
// fake code!
var overlays = google.maps.Map.getOverlays();
for (var i in overlays ){
if (overlays[i] instanceof google.maps.InfoWindow){
// do staff
}
}
Но ничего подобного не существует. Более того если InfoWindow был прицеплен к маркеру то у него нет позиции
google.maps.event.addListener(marker, "click", function(e){
var window = new google.maps.InfoWindow({
content: this.getPosition().toString()
}).open(map, this);
console.log(window.getPosition()) // undefined
});
google.maps.event.addListener(marker, "click", function(e){
var window = new google.maps.InfoWindow({
content: this.getPosition().toString(),
position : this.getPosition()
}).open(map, this);
console.log(window.getPosition()) // position
});
Но во втором варианте проблема в том что InfoWindow будет относиться не к маркеру (стрелочка указывает на центр верха маркера), а к точке к которой относиться маркер.
Поскольку InfoWindow не имеет позиции, то сравнивать приходиться не позиции а содержимое, это мало того что не удобно так еще и черевато всякими косяками. в общем этот вариант тоже не вариант.
Если все методы перепробованы а результата нет - прочтите инструкцию. Вооружившись этой самой инструкцией мы начинаем хачить класс google.maps.Marker
google.maps.Marker.prototype.openInfoWindow = function(content){
if (!(this.InfoWindow && this.InfoWindow.getContent() == content)){
this.InfoWindow = new google.maps.InfoWindow({
content: content
});
}
this.InfoWindow.open(this.map, this);
}
var myMarkerManager = new MarkerManager(
new google.maps.Map(document.getElementById("map3"), {
zoom: 5,
center: new google.maps.LatLng(50, 27),
mapTypeId: google.maps.MapTypeId.HYBRID
})
);
myMarkerManager.createMarker(new google.maps.LatLng(50.440951, 30.527181));
myMarkerManager.createMarker(new google.maps.LatLng(49.836944, 24.005000));
for (var i in myMarkerManager.markers){
google.maps.event.addListener(myMarkerManager.markers[i], "click", function(e){
myMarkerManager.map.setCenter(this.getPosition());
this.openInfoWindow(this.getPosition().toString());
});
}
Вот так все легко и просто :)
Свежие комментарии