2009-12-09 14 views

Antwort

143

Sie brauchen nur ein InfoWindow Objekt zu erstellen, einen Verweis auf sie halten, und wiederverwenden, wenn für alle Markierungen. :

Wenn Sie nur ein Infofenster wollen auf einmal angezeigt werden (wie das Verhalten von Google Maps ist), müssen Sie nur ein Info-Fenster erstellen, die Sie an verschiedenen Orten oder Markierungen auf der Karte Ereignissen zuweisen können (wie Benutzerklicks).

Daher können Sie wollen einfach nur das InfoWindow-Objekt erstellen, nachdem Sie Ihre Karte initialisieren, und dann behandeln den click Event-Handler Ihres Markers wie folgt. Angenommen, Sie haben einen Marker haben someMarker genannt:

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

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

+0

Ich mache das auch, aber ist es normal, dass das InfoWindow wie +1 Sekunde dauert, um auf dem nächsten Marker zu öffnen? manchmal öffnet es überhaupt nicht. Ich benutze den exakt gleichen Code – MJB

+0

Daniel, tolle Idee !! vorher habe ich versucht, manuell zu synchronisieren, aber es zeigt seltsame JavaScript-Fehler (wie "c ist null" in main.js oder etwas wie (123 außerhalb des Bereichs 43)). – Victor

-3

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

+2

das ist nicht richtig, ich kann so viel wie 20 infowindows auf meiner Karte öffnen. es ist v3 btw. – leo

+0

Okay, danke für die Korrektur. Ich wusste nicht, dass es in der Version 3 geändert hatte. –

0

Sie benötigen den Überblick über Ihre vorherigen InfoWindow Objekt zu halten und die schließen Methode auf sie aufrufen, wenn Sie das Click-Ereignis auf einem neuen Marker behandeln.

N.B Es ist nicht notwendig, das geteilte Info-Fenster-Objekt zu schließen, wenn Sie mit einem anderen Marker öffnen, wird das Original automatisch geschlossen. Einzelheiten finden Sie unter Daniel's answer.

+0

Ich weiß, dass dies eine alte Antwort ist, und die v3-API war zu der Zeit obskur ... Aber eigentlich ist es nicht notwendig, die 'close()' Methode aufzurufen, wenn a Ein einzelnes 'InfoWindow'-Objekt wird verwendet. Es wird automatisch geschlossen, wenn die Methode 'open()' erneut für dasselbe Objekt aufgerufen wird. –

+0

@ daniel-vassallo Danke für den Hinweis :) Ich habe Ihre Antwort entsprechend upvoted, es ist das nützlichste, denke ich. – RedBlueThing

+0

Danke @Cannonade :) –

26

Erstellen Sie Ihr Infowindow aus dem Bereich, damit Sie es teilen 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); 
    }); 
} 
+0

Danke. Mit "this" löste ich die meisten meiner Probleme. Ich verstehe immer noch nicht, wie benutzerdefinierte Inhalte innerhalb von setContent verwendet werden. Z.B. In meiner Marker-Schleife erstelle ich 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

+0

In meinem Fall öffnet sich das Fenster nur, wenn ich "this" in infowindow.open (map, this) verwende; Anstelle von "Marker". Thx für das Teilen Ihrer Lösung. – ownking

+0

Ich mache das auch, aber ist es normal, dass das infoWindow wie +1 Sekunde dauert, um auf dem nächsten Marker zu öffnen? manchmal öffnet es überhaupt nicht. Ich benutze genau den gleichen Code – MJB

11

Ich hatte das gleiche Problem, aber die beste Antwort löste es nicht vollständig, was ich in meiner for-Anweisung tun musste, war das, das sich auf meinen aktuellen Marker bezieht. 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);     
} 
+2

Die Art, wie Sie den ContentString übergeben, war für mich nützlich, thx. – ownking

+0

Sie haben mir ein Problem gelöst, Sir! Ungarische Macht! ;) – martincpt

0

Grundsätzlich wollen Sie eine Funktion, die Bezugnahme auf eine new InfoBox() => delegieren das Onclick-Ereignis hält. Während Ihre Markierungen (in einer Schleife) Erzeugen verwenden 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 asynchron zugeordnet und im Speicher gehalten. Jedes Mal, wenn Sie bindInfoBox() anrufen, wird stattdessen die Rückkehrfunktion aufgerufen. Auch praktisch, um die infoBoxOptions nur einmal zu übergeben!

In meinem Beispiel musste ich einen zusätzlichen Parameter zu der map hinzufügen, da meine Initialisierung durch Tab-Ereignisse verzögert wird.

InfoBoxOptions

3

ein bisschen spät, aber ich schaffte es nur eine haben Infofenster geöffnet von maken eine globale Variable Infofenster.

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

dann innerhalb des listner

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

infowindow.open(map, this); 
+1

Funktioniert super für mich :) – lumos

3

Deklarieren Sie eine GLOBAR var selectedInfoWindow; und es verwenden, die 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); 
}); 
-1

Gelöst es so:

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

Hier ist ein Lösung, die nicht nur ein InfoWindow erstellen muss, um es wiederzuverwenden. Sie können weiterhin viele InfoWindows erstellen, Sie müssen lediglich eine closeAllInfoWindows-Funktion erstellen und sie aufrufen, bevor Sie ein neues Infofenster öffnen. So , Ihren Code zu halten, müssen Sie nur:

  1. ein globales Array Erstellen Sie alle Infofenster speichern

    var infoWindows = []; 
    
  2. Shop jede neue infowindow im Array, kurz nach dem infowindow = new ...

    infoWindows.push(infoWindow); 
    
  3. die Funktion closeAllInfoWindows erstellen

    function closeAllInfoWindows() { 
        for (var i=0;i<infoWindows.length;i++) { 
         infoWindows[i].close(); 
        } 
    } 
    
  4. Rufen Sie in Ihrem Code kurz vor dem Öffnen des InfoWindows closeAllInfoWindows() auf.

Grüße,

Verwandte Themen