2009-12-09 8 views

Respuesta

143

Es necesario crear un solo InfoWindow objeto, mantener una referencia a la misma, y ​​volver a utilizar si para todos los marcadores. :

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

Por lo tanto, sólo puede crear el objeto InfoWindow justo después de inicializar el mapa, y luego manejar la click controladores de eventos de sus marcadores de la siguiente manera. Digamos que usted tiene un marcador llamado someMarker:

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

Entonces el InfoWindow debería cerrarse automáticamente cuando se hace clic en un nuevo marcador sin tener que llamar al método close().

+0

Hago esto también, pero ¿es normal que la ventana de información tarde más de 1 segundo en abrirse en el siguiente marcador? a veces no se abre en absoluto. Uso exactamente el mismo código – MJB

+0

Daniel, gran idea !! antes estaba intentando sincronizar manualmente, pero muestra extraños errores de javascript (como "c es nulo" en main.js, o algo así como (123 fuera de rango 43)). – Victor

-3

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

+2

que no está bien, puedo abrir hasta 20 infowindows en mi mapa. es v3 por cierto. – leo

+0

Bien, gracias por corregir. No sabía que había cambiado en la versión 3. –

0

que necesita para mantener un registro de su InfoWindow objeto anterior y llamar a la estrecha método en él cuando manipule el evento click en un nuevo marcador .

N.B No es necesario llamar de cerca al objeto de la ventana de información compartida, la llamada abierta con un marcador diferente cerrará automáticamente el original. Ver Daniel's answer para más detalles.

+0

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 método 'close()', si se utiliza el único objeto 'InfoWindow'. Se cerrará automáticamente si se llama nuevamente al método 'open()' en el mismo objeto. –

+0

@ daniel-vassallo Gracias por la nota :) He votado su respuesta en consecuencia, es la más útil, creo. – RedBlueThing

+0

Gracias @Cannonade :) –

26

Crea tu ventana de información fuera del alcance para que puedas compartirla.

Aquí está 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); 
    }); 
} 
+0

Gracias. Usar "esto" resolvió la mayoría de mis problemas. Todavía no entiendo cómo usar contenido personalizado dentro de setContent. P.ej. en mi ciclo marker, 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

+0

En mi caso, la ventana solo se abre cuando utilizo "this" en infowindow.open (map, this); En lugar de "marcador". Gracias por compartir tu solución. – ownking

+0

Hago esto también, pero ¿es normal que la ventana de información tarde más de 1 segundo para abrir en el siguiente marcador? a veces no se abre en absoluto. Utilizo exactamente el mismo código – MJB

11

Tuve el mismo problema, pero la mejor respuesta no lo resolvió completamente, lo que tenía que hacer en mi declaración fue usar esto relacionado con mi marcador actual. Tal vez 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);     
} 
+2

La forma en que pasaste contentString fue útil para mí, gracias. – ownking

+0

¡Usted me ha solucionado un problema, señor! Poder húngaro! ;) – martincpt

0

Básicamente, usted quiere una función que mantiene la referencia a uno new InfoBox() => delegar el evento onclick. bien la creación de sus marcadores (en un bucle) utilizan bindInfoBox(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 infoBox se asigna de forma asíncrona y se mantiene en la memoria. Cada vez que llame al bindInfoBox(), se llamará a la función de retorno. ¡También es útil pasar el infoBoxOptions solo una vez!

En mi ejemplo, he tenido que agregar un parámetro adicional al map ya que mi inicialización se ve demorada por eventos de tabulación.

InfoBoxOptions

3

un poco tarde, pero me las arreglé para tener sólo una ventana de información abierta por maken InfoWindow una variable global.

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

entonces dentro de la listner

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

infowindow.open(map, this); 
+1

Funciona muy bien para mí :) – lumos

3

Declarar una Globar var selectedInfoWindow; y utilizarlo para mantener la ventana de información abierto:

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); 
}); 
-1

solucionado 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); 
0

Aquí hay una solución que no necesita crear solo una ventana de información para reutilizarla. Puede seguir creando muchas ventanas de información, lo único que necesita es crear una función closeAllInfoWindows y llamarla antes de abrir una nueva ventana de información. Por lo tanto, el mantenimiento de su código, sólo tiene que:

  1. crear una matriz global para almacenar todas las ventanas de información

    var infoWindows = []; 
    
  2. almacenar cada nueva infoWindow en la matriz, justo después de la infoWindow = new ...

    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,

Cuestiones relacionadas