Avere una sola InfoWindow aperta nell'API di Google Maps v3


85

Devo avere una sola InfoWindow aperta sulla mia mappa di Google. Devo chiudere tutte le altre InfoWindows prima di aprirne una nuova.

Qualcuno può mostrarmi come farlo?


Cosa hai provato?
IgniteCoders

Risposte:


151

È necessario creare un solo InfoWindowoggetto, mantenere un riferimento ad esso e riutilizzarlo per tutti i marker. Citando dai documenti dell'API di Google Maps :

Se desideri che venga visualizzata solo una finestra informativa alla volta (come il comportamento su Google Maps), devi creare solo una finestra informativa, che puoi riassegnare a diverse posizioni o indicatori sugli eventi della mappa (come i clic dell'utente).

Pertanto, potresti semplicemente voler creare l' InfoWindowoggetto subito dopo aver inizializzato la mappa e quindi gestire i clickgestori di eventi dei tuoi marcatori come segue. Supponiamo che tu abbia un marker chiamato someMarker:

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

Quindi InfoWindowdovrebbe chiudersi automaticamente quando si fa clic su un nuovo marker senza dover chiamare il close()metodo.


Anch'io lo faccio ma è normale che infoWindow impieghi +1 secondo per aprirsi sul marker successivo? a volte non si apre affatto. Uso lo stesso identico codice
MJB

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

30

Crea la tua finestra informativa fuori dall'ambito in modo da poterla condividere.

Qui c'è 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);
  });
}

Grazie. L'utilizzo di "this" ha risolto la maggior parte dei miei problemi. Continuo a non capire come utilizzare il contenuto personalizzato all'interno di setContent. Ad esempio, nel mio loop marker, creo una variabile contentHtml utilizzando la variabile "i" e collegandola a un oggetto database. Come posso passare quella variabile contentHtml all'ascoltatore?
Ryan

Nel mio caso la finestra si apre solo quando uso "this" in infowindow.open (map, this); Invece di "marker". Grazie per aver condiviso la tua soluzione.
proprietario del

Anch'io lo faccio ma è normale che infoWindow impieghi +1 secondo per aprirsi sul marker successivo? a volte non si apre affatto. Uso lo stesso identico codice
MJB

14

Ho avuto lo stesso problema ma la risposta migliore non lo ha risolto completamente, quello che dovevo fare nella mia dichiarazione for era usare il this relativo al mio attuale marker. 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 passi il contentString è stato utile per me, grazie.
proprietario del

4

un po 'tardi, ma sono riuscito ad avere una sola finestra informativa aperta rendendola una variabile globale.

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

quindi all'interno del listner

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

infowindow.open(map, this);

1
Funziona alla grande per me :)
lumos

4

Dichiara un globar var selectedInfoWindow;e usalo per mantenere la finestra informativa aperta:

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

0

È necessario tenere traccia del precedente oggetto InfoWindow e chiamare il metodo di chiusura su di esso quando si gestisce l'evento clic su un nuovo indicatore .

NB Non è necessario chiamare close sull'oggetto finestra info condivisa, chiamando open con un marker diverso si chiuderà automaticamente l'originale. Vedi la risposta di Daniel per i dettagli.


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

@ daniel-vassallo Grazie per la nota :) Ho votato di conseguenza la tua risposta, è la più utile credo.
RedBlueThing

0

Fondamentalmente vuoi una funzione che mantenga il riferimento a uno new InfoBox()=> delegare l'evento onclick. Mentre crei i tuoi marker (in un ciclo) usabindInfoBox(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 infoBoxviene assegnato in modo asincrono e mantenuto in memoria. Ogni volta che chiami bindInfoBox()la funzione return verrà invece chiamata. Comodo anche per passare l' infoBoxOptionsunica volta!

Nel mio esempio ho dovuto aggiungere un parametro extra a mappoiché la mia inizializzazione è ritardata dagli eventi di tabulazione.

InfoBoxOptions


0

Ecco una soluzione che non ha bisogno di creare una sola infoWindow per riutilizzarla. Puoi continuare a creare molte infoWindows, l'unica cosa di cui hai bisogno è creare una funzione closeAllInfoWindows e chiamarla prima di aprire una nuova infowindow. Quindi, mantenendo il codice, devi solo:

  1. Crea un array globale per archiviare tutte le infoWindows

    var infoWindows = [];
    
  2. Memorizza ogni nuova infoWindow nell'array, subito dopo infoWindow = new ...

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

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

Saluti,


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

-4

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


2
non è corretto, posso aprire fino a 20 finestre informative sulla mappa. è v3 btw.
leo

Va bene, grazie per la correzione. Non sapevo che fosse cambiato nella versione 3.
Kimmo Puputti
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.