Öffnen Sie nur ein InfoWindow in Google Maps API v3

85

Ich muss nur ein InfoWindow auf meiner Google Map geöffnet haben. Ich muss alle anderen InfoWindows schließen, bevor ich ein neues öffne.

Kann mir jemand zeigen, wie das geht?

Löwe
quelle
Was hast du versucht?
IgniteCoders

Antworten:

151

Sie müssen nur ein InfoWindowObjekt erstellen , einen Verweis darauf behalten und es für alle Markierungen wiederverwenden. Zitieren aus den Google Maps API-Dokumenten :

Wenn jeweils nur ein Infofenster angezeigt werden soll (wie dies bei Google Maps der Fall ist), müssen Sie nur ein Infofenster erstellen, das Sie bei Kartenereignissen (z. B. Benutzerklicks) verschiedenen Orten oder Markierungen zuweisen können.

Daher möchten Sie das InfoWindowObjekt möglicherweise einfach direkt nach der Initialisierung Ihrer Karte erstellen und dann die clickEreignishandler Ihrer Markierungen wie folgt behandeln. Angenommen, Sie haben einen Marker namens someMarker:

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

Dann InfoWindowsollte sich das automatisch schließen, wenn Sie auf eine neue Markierung klicken, ohne die close()Methode aufrufen zu müssen .

Daniel Vassallo
quelle
Ich mache das auch, aber ist es normal, dass das infoWindow etwa +1 Sekunde braucht, um beim nächsten Marker geöffnet zu werden? manchmal öffnet es sich überhaupt nicht. Ich benutze genau den gleichen Code
MJB
Daniel, tolle Idee !! vorher habe ich versucht, manuell zu synchronisieren, aber es zeigt seltsame Javascript-Fehler (wie "c ist null" in main.js oder so etwas wie (123 außerhalb des Bereichs 43)).
Victor
30

Erstellen Sie Ihr Infofenster außerhalb des Bereichs, damit Sie es freigeben können.

Hier ist ein einfaches Beispiel:

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
quelle
Danke dir. Die Verwendung von "this" löste die meisten meiner Probleme. Ich verstehe immer noch nicht, wie man benutzerdefinierte Inhalte in setContent verwendet. Beispielsweise erstelle ich in meiner Markierungsschleife eine contentHtml-Variable mit der Variablen "i" und verknüpfe sie mit einem Datenbankobjekt. Wie kann ich diese contentHtml-Variable an den Listener übergeben?
Ryan
In meinem Fall öffnet sich das Fenster nur, wenn ich "this" in infowindow.open (map, this) verwende; Anstelle von "Marker". Vielen Dank für die Freigabe Ihrer Lösung.
Ownking
Ich mache das auch, aber ist es normal, dass das infoWindow etwa +1 Sekunde braucht, um beim nächsten Marker geöffnet zu werden? manchmal öffnet es sich überhaupt nicht. Ich benutze genau den gleichen Code
MJB
14

Ich hatte das gleiche Problem, aber die beste Antwort löste es nicht vollständig. Was ich in meiner for-Anweisung tun musste, war, dies in Bezug auf meinen aktuellen Marker zu verwenden. Vielleicht hilft das jemandem.

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
quelle
2
Die Art und Weise, wie Sie den contentString übergeben, war für mich nützlich, danke.
Ownking
4

ein bisschen spät, aber ich habe es geschafft, nur ein Infofenster zu öffnen, indem ich infowindow zu einer globalen Variablen gemacht habe.

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

dann im Listener

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

infowindow.open(map, this);
user2827958
quelle
1
Funktioniert
super
4

Deklarieren Sie einen Globar var selectedInfoWindow;und verwenden Sie ihn, um das geöffnete Infofenster zu halten:

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
quelle
0

Sie müssen Ihr vorheriges InfoWindow- Objekt verfolgen und die Methode close aufrufen , wenn Sie das Klickereignis für eine neue Markierung behandeln .

Hinweis: Es ist nicht erforderlich, close für das Objekt des freigegebenen Infofensters aufzurufen. Wenn Sie open mit einer anderen Markierung aufrufen, wird das Original automatisch geschlossen. Siehe Daniels Antwort für Details.

RedBlueThing
quelle
Ich weiß, dass dies eine alte Antwort ist und die v3-API zu diesem Zeitpunkt dunkel war ... Aber tatsächlich besteht keine Notwendigkeit, die close()Methode aufzurufen , wenn ein einzelnes InfoWindowObjekt verwendet wird. Es wird automatisch geschlossen, wenn die open()Methode für dasselbe Objekt erneut aufgerufen wird.
Daniel Vassallo
@ daniel-vassallo Danke für den Hinweis :) Ich habe deine Antwort entsprechend positiv bewertet, es ist das nützlichste, was ich denke.
RedBlueThing
0

Grundsätzlich möchten Sie eine Funktion, die auf eins verweist new InfoBox()=> das onclick-Ereignis delegieren. Verwenden Sie beim Erstellen Ihrer Marker (in einer Schleife)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 infoBoxwird asynchron zugewiesen und gespeichert. Jedes Mal, wenn Sie bindInfoBox()die Rückgabefunktion aufrufen, wird stattdessen aufgerufen. Auch praktisch, um das infoBoxOptionsnur einmal zu bestehen!

In meinem Beispiel musste ich dem einen zusätzlichen Parameter hinzufügen, mapda meine Initialisierung durch Registerkartenereignisse verzögert wird.

InfoBoxOptions

Tim Vermaelen
quelle
0

Hier ist eine Lösung, bei der nicht nur ein infoWindow erstellt werden muss, um es wiederzuverwenden. Sie können weiterhin viele infoWindows erstellen. Sie müssen lediglich eine closeAllInfoWindows-Funktion erstellen und diese aufrufen, bevor Sie ein neues Infowindow öffnen. Wenn Sie also Ihren Code behalten, müssen Sie nur:

  1. Erstellen Sie ein globales Array, um alle infoWindows zu speichern

    var infoWindows = [];
  2. Speichern Sie jedes neue infoWindow im Array, direkt nach dem infoWindow = new ...

    infoWindows.push(infoWindow);
  3. Erstellen Sie die Funktion closeAllInfoWindows

    function closeAllInfoWindows() {
        for (var i=0;i<infoWindows.length;i++) {
            infoWindows[i].close();
        }
    }
  4. Rufen Sie in Ihrem Code closeAllInfoWindows () auf, bevor Sie das infoWindow öffnen.

Grüße,

Jortx
quelle
-1

Es wurde folgendermaßen gelöst:

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
quelle
-4

Mit Google Maps können Sie nur ein Infofenster öffnen. Wenn Sie also ein neues Fenster öffnen, wird das andere automatisch geschlossen.

Kimmo Puputti
quelle
2
das ist nicht richtig, ich kann bis zu 20 infowindows auf meiner karte öffnen. es ist übrigens v3.
Leo
Okay, danke für die Korrektur. Ich wusste nicht, dass es sich in Version 3 geändert hatte.
Kimmo Puputti