javascript - style - infowindow google maps
Google Maps API v3 agregando una ventana de informaciĆ³n a cada marcador (10)
El add_marker todavía tiene un problema de cierre, porque usa la variable de marcador fuera del alcance google.maps.event.addListener.
Una mejor implementación sería:
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 = this.note;
info_window.open(this.getMap(), this);
});
return marker;
}
También utilicé el mapa del marcador, de esta manera no es necesario que pase el objeto del mapa de Google; es probable que desee utilizar el mapa al que pertenece el marcador de todos modos.
NOTA: estoy usando v3 de la API de Google Maps
Estoy tratando de agregar una ventana de información a cada marcador que coloqué en el mapa. Actualmente estoy haciendo esto con el siguiente código:
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);
}
El problema es que cuando hago clic en un marcador, solo aparece la ventana de información del último marcador agregado. También para que quede claro, la ventana de información aparece junto al último marcador en el que el marcador no hizo clic. Me imagino que mi problema está en la porción addListener pero no soy postitivo. ¿Algunas ideas?
En mi caso (usando JavaScript insidde Razor) Esto funcionó perfectamente dentro de un bucle Foreach
google.maps.event.addListener(marker, ''click'', function() {
marker.info.open(map, this);
});
Está teniendo un problema de cierre muy común en el ciclo for in
:
Las variables incluidas en un cierre comparten el mismo entorno único, por lo que cuando se llame al click
de addListener
, el ciclo habrá seguido su curso y la variable de info
se dejará apuntando al último objeto, que pasa a ser el último InfoWindow
creado.
En este caso, una manera fácil de resolver este problema sería aumentar su objeto Marker
con 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);
});
Este puede ser un tema bastante complicado si no está familiarizado con el funcionamiento de los cierres. Puede consultar el siguiente artículo de Mozilla para una breve introducción:
También tenga en cuenta que la API v3 permite múltiples InfoWindow
s en el mapa. Si tiene la intención de tener solo una InfoWindow
visible en ese momento, debería utilizar un único objeto InfoWindow
y luego abrirlo y cambiar su contenido cada vez que se haga clic en el marcador ( Source ).
Hola a todos. No sé si esta es la solución óptima, pero pensé que la publicaría aquí para ayudar a la gente en el futuro. Comente si ve algo que deba cambiarse.
Mi para bucles es ahora:
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);
}
Y add_marker
se define como:
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;
}
Puede usar info_window.close () para apagar la ventana info_ en cualquier momento. Espero que esto ayude a alguien.
La única forma en que finalmente pude hacer que esto funcionara fue creando una matriz en JavaScript. Los elementos de la matriz hacen referencia a las diversas ventanas de información (se crea una ventana de información para cada marcador en el mapa). Cada elemento de matriz contiene el texto único para su marcador de mapa apropiado. Definí el evento de JavaScript para cada ventana de información en función del elemento de la matriz. Y cuando se activa el evento, utilizo la palabra clave "this" para hacer referencia al elemento de la matriz para hacer referencia al valor apropiado para mostrar.
var map = new google.maps.Map(document.getElementById(''map-div''), mapOptions);
zipcircle = [];
for (var zip in zipmap) {
var circleoptions = {
strokeOpacity: 0.8,
strokeWeight: 1,
fillOpacity: 0.35,
map: map,
center: zipmap[zip].center,
radius: 100
};
zipcircle[zipmap[zip].zipkey] = new google.maps.Circle(circleoptions);
zipcircle[zipmap[zip].zipkey].infowindowtext = zipmap[zip].popuptext;
zipcircle[zipmap[zip].zipkey].infowindow = new google.maps.InfoWindow();
google.maps.event.addListener(zipcircle[zipmap[zip].zipkey], ''click'', function() {
this.infowindow.setContent(this.infowindowtext);
this.infowindow.open(map, this);
});
}
Prueba esto:
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);
}
Puedes usar this
en el evento:
google.maps.event.addListener(marker, ''click'', function() {
// this = marker
var marker_map = this.getMap();
this.info.open(marker_map);
// this.info.open(marker_map, this);
// Note: If you call open() without passing a marker, the InfoWindow will use the position specified upon construction through the InfoWindowOptions object literal.
});
Tuve un problema muy similar, pero en ActionScript 3: Stack Over Flow: Dynamic Google Maps API, ventana de información Problema de contenido HTML
Estaba tratando de extraer información única en el contenido html de los tooltips de una base de datos y encontré que estaba obteniendo la información del último marcador que agregué en cada marcador.
Suponiendo que no se trate de un problema específico de ActionScript, la solución de JochenJung no funcionará. Mira la solución que publiqué en mi problema y mira si puedes aplicarla aquí. Esto parece ser un problema grave con Map API.
Tuve un problema similar. Si todo lo que desea es que se muestre alguna información cuando coloca el mouse sobre un marcador, en lugar de hacer clic en él, entonces descubrí que una buena alternativa para usar una ventana de información era establecer un título en el marcador. De esta manera cada vez que pase el mouse sobre el marcador, el título se muestra como una etiqueta ALT. ''marker.setTitle ('' Marker ''+ id);'' Elimina la necesidad de crear un oyente para el marcador también
para las API de plugin de Earth, crea el globo fuera de tu loop y pasa tu contador a la función para obtener contenido único para cada marca de posición.
function createBalloon(placemark, i, event) {
var p = placemark;
var j = i;
google.earth.addEventListener(p, ''click'', function (event) {
// prevent the default balloon from popping up
event.preventDefault();
var balloon = ge.createHtmlStringBalloon('''');
balloon.setFeature(event.getTarget());
balloon.setContentString(''iframePath#'' + j);
ge.setBalloon(balloon);
});
}