2009-12-09 19 views

risposta

143

È necessario creare un solo InfoWindow oggetto, mantenere un riferimento ad essa, e riutilizzare se per tutti i marcatori. :

Se si desidera solo una finestra di informazioni per visualizzare in un momento (come è il comportamento su Google Maps), è sufficiente creare una finestra di informazioni, che è possibile riassegnare in luoghi o marcatori diversi, su Mappa Eventi (come i clic dell'utente).

Pertanto, si può semplicemente voler creare l'oggetto InfoWindow subito dopo si inizializza la mappa, e quindi gestire le click gestori di eventi dei vostri marcatori come segue. Diciamo che avete un marcatore chiamato someMarker:

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

Poi il InfoWindow dovrebbe chiude automaticamente quando si fa clic su un nuovo marcatore, senza dover chiamare il metodo close().

+0

Anche io lo faccio, ma è normale che infoWindow impieghi +1 secondo per aprirsi sul prossimo marcatore? a volte non si apre affatto. Io uso lo stesso identico codice – MJB

+0

Daniel, ottima idea !! prima stavo cercando di sincronizzare manualmente, ma mostra strani errori javascript (come "c è nullo" in main.js, o qualcosa di simile (123 su un intervallo 43)). – Victor

-3

Google Maps consente di avere solo una finestra informativa aperta. Quindi se apri una nuova finestra, l'altra si chiude automaticamente.

+2

che non è giusto, posso aprire fino a 20 infowindows sulla mia mappa. è v3 btw. – leo

+0

Ok, grazie per la correzione. Non sapevo che fosse cambiato nella versione 3. –

0

è necessario tenere traccia del vostro precedente InfoWindow oggetto e chiamare il vicino metodo su di esso quando si gestisce l'evento click su un nuovo marcatore .

N.B Non è necessario chiamare da vicino l'oggetto della finestra di informazioni condivise, la chiamata aperta con un marcatore diverso chiuderà automaticamente l'originale. Vedi Daniel's answer per i dettagli.

+0

So che questa è una vecchia risposta, e l'API v3 era oscura al momento ... Ma in realtà non c'è bisogno di chiamare il metodo 'close()', se viene utilizzato un singolo oggetto 'InfoWindow'. Si chiuderà automaticamente se il metodo 'open()' viene chiamato di nuovo sullo stesso oggetto. –

+0

@ daniel-vassallo Grazie per la nota :) Ho aumentato la tua risposta di conseguenza, è il più utile che penso. – RedBlueThing

+0

Grazie a @Cannonade :) –

26

Crea la tua finestra fuori dal campo di applicazione in modo da poterla condividere.

Ecco un semplice esempio:

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

Grazie. Usando "questo" ho risolto la maggior parte dei miei problemi. Non riesco ancora a capire come utilizzare i contenuti personalizzati all'interno di setContent. Per esempio. nel mio loop marker, creo una variabile contentHtml usando la variabile "i" e collegandola a un oggetto di database. Come posso passare la variabile contentHtml al listener? – Ryan

+0

Nel mio caso la finestra si apre solo quando uso "this" in infowindow.open (map, this); Invece di "marker". Thx per condividere la tua soluzione. – ownking

+0

Anche io lo faccio, ma è normale che infoWindow impieghi +1 secondo per aprirsi sul prossimo marcatore? a volte non si apre affatto. Io uso lo stesso identico codice – MJB

11

Ho avuto lo stesso problema ma la risposta migliore non l'ha risolta completamente, quello che dovevo fare nella mia affermazione era usare ciò relativo al mio attuale marcatore. Forse questo aiuta qualcuno.

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

Il modo in cui hai passato il contentString mi è stato utile, grazie. – ownking

+0

Mi hai risolto un problema signore! Potere ungherese! ;) – martincpt

0

Fondamentalmente si desidera una funzione che mantiene riferimento ad uno new InfoBox() => delegare l'evento onclick. Durante la creazione dei marcatori (in un ciclo) usano 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 è assegnato in modo asincrono e tenuto in memoria. Ogni volta che si chiama bindInfoBox() verrà richiamata la funzione di ritorno. Anche utile per passare il infoBoxOptions solo una volta!

Nel mio esempio ho dovuto aggiungere un parametro aggiuntivo allo map poiché la mia inizializzazione è ritardata da eventi di tabulazione.

InfoBoxOptions

3

un po 'in ritardo, ma sono riuscito ad avere un solo infowindow aperta maken infowindow una variabile globale.

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

poi dentro The Listener

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

infowindow.open(map, this); 
+1

Funziona alla grande per me :) – lumos

3

Dichiarare un Globar var selectedInfoWindow; e utilizzarlo per tenere la finestra di informazioni aperto:

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

risolto in questo modo:

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

Ecco a soluzione che non ha bisogno di creare solo una infoWindow per riutilizzarla. Puoi continuare a creare molte informazioni su InfoWindows, l'unica cosa di cui hai bisogno è creare una funzione closeAllInfoWindows e chiamarla prima di aprire una nuova finestra di apertura. Quindi, mantenere il vostro codice, è solo bisogno di:

  1. creare un array globale per memorizzare tutti i infoWindows

    var infoWindows = []; 
    
  2. memorizzare ogni nuova infowindow nella matrice, subito dopo l'infowindow = new ...

    infoWindows.push(infoWindow); 
    
  3. creare la funzione closeAllInfoWindows

    function closeAllInfoWindows() { 
        for (var i=0;i<infoWindows.length;i++) { 
         infoWindows[i].close(); 
        } 
    } 
    
  4. Nel codice, chiamare closeAllInfoWindows() prima di aprire InfoWindow.

saluti,

Problemi correlati