Tener solo una ventana de información abierta en Google Maps API v3

85

Necesito tener solo una ventana de información abierta en mi mapa de Google. Necesito cerrar todas las demás InfoWindows antes de abrir una nueva.

¿Alguien puede mostrarme cómo hacer esto?

León
fuente
¿Qué intentaste?
IgniteCoders

Respuestas:

151

Necesita crear un solo InfoWindowobjeto, mantener una referencia a él y reutilizarlo para todos los marcadores. Citando los documentos de la API de Google Maps :

Si solo desea que se muestre una ventana de información a la vez (como es el comportamiento en Google Maps), solo necesita crear una ventana de información, que puede reasignar a diferentes ubicaciones o marcadores en eventos del mapa (como los clics del usuario).

Por lo tanto, puede simplemente querer crear el InfoWindowobjeto justo después de inicializar su mapa y luego manejar los clickcontroladores de eventos de sus marcadores de la siguiente manera. Digamos que tiene un marcador llamado someMarker:

google.maps.event.addListener(someMarker, 'click', function() {
   infowindow.setContent('Hello World');
   infowindow.open(map, this);
});

Luego, InfoWindowdebería cerrarse automáticamente al hacer clic en un nuevo marcador sin tener que llamar al close()método.

Daniel Vassallo
fuente
Yo también hago esto, pero ¿es normal que la ventana de información tarde como +1 segundo en abrirse en el siguiente marcador? a veces no se abre en absoluto. Utilizo exactamente el mismo código
MJB
Daniel, gran idea !! antes de eso, estaba tratando de sincronizar manualmente, pero muestra errores extraños de JavaScript (como "c es nulo" en main.js, o algo como (123 fuera del rango 43)).
Victor
30

Cree su ventana de información fuera del alcance para poder compartirla.

He aquí un ejemplo sencillo:

var markers = [AnArrayOfMarkers];
var infowindow = new google.maps.InfoWindow();

for (var i = 0, marker; marker = markers[i]; i++) {
  google.maps.event.addListener(marker, 'click', function(e) {
    infowindow.setContent('Marker position: ' + this.getPosition());
    infowindow.open(map, this);
  });
}
skarE
fuente
Gracias. Usar "esto" resolvió la mayoría de mis problemas. Todavía no entiendo cómo usar contenido personalizado dentro de setContent. Por ejemplo, en mi bucle de marcador, creo una variable contentHtml usando la variable "i" y vinculándola a un objeto de base de datos. ¿Cómo puedo pasar esa variable contentHtml al oyente?
Ryan
En mi caso, la ventana solo se abre cuando uso "esto" en infowindow.open (mapa, esto); En lugar de "marcador". Gracias por compartir su solución.
ownking
Yo también hago esto, pero ¿es normal que la ventana de información tarde como +1 segundo en abrirse en el siguiente marcador? a veces no se abre en absoluto. Utilizo exactamente el mismo código
MJB
14

Tuve el mismo problema, pero la mejor respuesta no lo resolvió por completo, lo que tenía que hacer en mi declaración for era usar esto relacionado con mi marcador actual. Quizás esto ayude a alguien.

for(var i = 0; i < markers.length; i++){
    name = markers[i].getAttribute("name");
    address = markers[i].getAttribute("address");        
    point = new google.maps.LatLng(parseFloat(markers[i].getAttribute("lat")), parseFloat(markers[i].getAttribute("lng")));                                     
    contentString = '<div style="font-family: Lucida Grande, Arial, sans-serif;>'+'<div><b>'+ name +'</b></div>'+'<div>'+ address +'</div>';                    
    marker = new google.maps.Marker({                       
        map: map,
        position: point,
        title: name+" "+address,
        buborek: contentString 
    });                                     
    google.maps.event.addListener(marker, 'click', function(){
        infowindow.setContent(this.buborek); 
        infowindow.open(map,this); 
    });                                                         
    marker.setMap(map);                 
}
Ferenc Takacs
fuente
2
La forma en que pasa el contentString fue útil para mí, gracias.
ownking el
4

un poco tarde, pero me las arreglé para tener solo una ventana de información abierta al hacer de la ventana de información una variable global.

var infowindow = new google.maps.InfoWindow({});

luego dentro del listner

infowindow.close();
infowindow = new google.maps.InfoWindow({   
    content: '<h1>'+arrondissement+'</h1>'+ gemeentesFiltered                           
});

infowindow.open(map, this);
usuario2827958
fuente
1
Funciona muy bien para mí :)
lumos
4

Declare una barra global var selectedInfoWindow;y úsela para mantener la ventana de información abierta:

var infoWindow = new google.maps.InfoWindow({
    content: content
});

// Open the infowindow on marker click
google.maps.event.addListener(marker, "click", function() {
    //Check if there some info window selected and if is opened then close it
    if (selectedInfoWindow != null && selectedInfoWindow.getMap() != null) {
        selectedInfoWindow.close();
        //If the clicked window is the selected window, deselect it and return
        if (selectedInfoWindow == infoWindow) {
            selectedInfoWindow = null;
            return;
        }
    }
    //If arrive here, that mean you should open the new info window 
    //because is different from the selected
    selectedInfoWindow = infoWindow;
    selectedInfoWindow.open(map, marker);
});
IgniteCoders
fuente
0

Debe realizar un seguimiento de su objeto InfoWindow anterior y llamar al método de cierre cuando maneja el evento de clic en un nuevo marcador .

NB: No es necesario llamar a cerrar en el objeto de la ventana de información compartida, llamar a abrir con un marcador diferente cerrará automáticamente el original. Vea la respuesta de Daniel para más detalles.

RojoAzulCosa
fuente
Sé que esta es una respuesta antigua, y la API v3 era oscura en ese momento ... Pero en realidad no hay necesidad de llamar al close()método, si InfoWindowse usa un solo objeto. Se cerrará automáticamente si open()se vuelve a llamar al método en el mismo objeto.
Daniel Vassallo
@ daniel-vassallo Gracias por la nota :) He votado a favor de tu respuesta en consecuencia, creo que es la más útil.
RedBlueThing
0

Básicamente, desea una función que mantenga la referencia a uno new InfoBox()=> delegar el evento onclick. Mientras crea sus marcadores (en un bucle) usebindInfoBox(xhr, map, marker);

// @param(project): xhr : data for infoBox template
// @param(map): object : google.maps.map
// @param(marker): object : google.maps.marker
bindInfoBox: (function () {
    var options = $.extend({}, cfg.infoBoxOptions, { pixelOffset: new google.maps.Size(-450, -30) }),
        infoBox = new window.InfoBox(options);

    return function (project, map, marker) {
        var tpl = renderTemplate(project, cfg.infoBoxTpl); // similar to Mustache, Handlebars

        google.maps.event.addListener(marker, 'click', function () {
            infoBox.setContent(tpl);
            infoBox.open(map, marker);
        });
    };
}())

var infoBoxse asigna de forma asincrónica y se guarda en la memoria. Cada vez que llame, se llamará a bindInfoBox()la función de retorno. También es útil para pasar elinfoBoxOptions solo una vez!

En mi ejemplo, tuve que agregar un parámetro adicional al mapya que mi inicialización se retrasa por eventos de pestaña.

InfoBoxOptions

Tim Vermaelen
fuente
0

Aquí hay una solución que no necesita crear solo una ventana de información para reutilizarla. Puede continuar creando muchas infoWindows, lo único que necesita es crear una función closeAllInfoWindows y llamarla antes de abrir una nueva ventana de información. Entonces, manteniendo su código, solo necesita:

  1. Cree una matriz global para almacenar toda la información de Windows

    var infoWindows = [];
    
  2. Almacene cada nueva ventana de información en la matriz, justo después de la ventana de información = nueva ...

    infoWindows.push(infoWindow);
    
  3. Crear la función closeAllInfoWindows

    function closeAllInfoWindows() {
        for (var i=0;i<infoWindows.length;i++) {
            infoWindows[i].close();
        }
    }
    
  4. En su código, llame a closeAllInfoWindows () justo antes de abrir la ventana de información.

Saludos,

Jortx
fuente
-1

Lo resolvió de esta manera:

function window(content){
    google.maps.event.addListener(marker,'click', (function(){
        infowindow.close();
        infowindow = new google.maps.InfoWindow({
            content: content
        });
        infowindow.open(map, this);
    }))
}
window(contentHtml);
Bilal Boulaich
fuente
-4

Google Maps le permite tener solo una ventana de información abierta. Entonces, si abre una nueva ventana, la otra se cierra automáticamente.

Kimmo Puputti
fuente
2
eso no es correcto, puedo abrir hasta 20 ventanas de información en mi mapa. es v3 por cierto.
leo
Bien, gracias por corregirlo. No sabía que había cambiado en la versión 3.
Kimmo Puputti