Miej tylko jedno okno InfoWindow otwarte w Google Maps API v3

85

Muszę mieć otwarte tylko jedno okno InfoWindow na mojej Mapie Google. Muszę zamknąć wszystkie inne okna InfoWindows, zanim otworzę nowe.

Czy ktoś może mi pokazać, jak to zrobić?

Lew
źródło
Czego próbowałeś?
IgniteCoders

Odpowiedzi:

151

Musisz utworzyć tylko jeden InfoWindowobiekt, zachować do niego odniesienie i użyć go ponownie dla wszystkich znaczników. Cytat z Dokumentów Google Maps API :

Jeśli chcesz, aby w danym momencie było wyświetlane tylko jedno okno informacyjne (tak jak dzieje się to w Mapach Google), musisz utworzyć tylko jedno okno informacyjne, które możesz przypisać do różnych lokalizacji lub znaczników po zdarzeniach na mapie (takich jak kliknięcia użytkowników).

Dlatego możesz po prostu chcieć utworzyć InfoWindowobiekt zaraz po zainicjowaniu mapy, a następnie obsłużyć clickprogramy obsługi zdarzeń swoich znaczników w następujący sposób. Powiedzmy, że masz znacznik o nazwie someMarker:

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

Następnie InfoWindowpowinien automatycznie zamknąć się po kliknięciu nowego znacznika bez konieczności wywoływania close()metody.

Daniel Vassallo
źródło
Ja też to robię, ale czy to normalne, że otwarcie okna infoWindow przy następnym znaczniku zajmuje około +1 sekundy? czasami w ogóle się nie otwiera. Używam dokładnie tego samego kodu
MJB
Daniel, świetny pomysł !! wcześniej próbowałem synchronizować ręcznie, ale pokazuje dziwne błędy javascript (np. „c is null” w main.js lub coś w rodzaju (123 poza zakresem 43)).
Victor,
30

Utwórz swoje okno informacyjne poza zakresem, aby móc je udostępniać.

Oto prosty przykład:

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
źródło
Dziękuję Ci. Używanie „tego” rozwiązało większość moich problemów. Nadal nie rozumiem, jak używać niestandardowej zawartości wewnątrz setContent. Np. W mojej pętli znaczników tworzę zmienną contentHtml używając zmiennej "i" i łączę ją z obiektem bazy danych. Jak mogę przekazać tę zmienną contentHtml do odbiornika?
Ryan,
W moim przypadku okno otwiera się tylko wtedy, gdy używam "this" w infowindow.open (mapa, to); Zamiast „znacznika”. Dzięki za udostępnienie rozwiązania.
ownking
Ja też to robię, ale czy to normalne, że otwarcie okna infoWindow przy następnym znaczniku zajmuje około +1 sekundy? czasami w ogóle się nie otwiera. Używam dokładnie tego samego kodu
MJB
14

Miałem ten sam problem, ale najlepsza odpowiedź nie rozwiązała go całkowicie, co musiałem zrobić w moim oświadczeniu for, używając tego odnoszącego się do mojego obecnego markera. Może to komuś pomoże.

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
źródło
2
Sposób w jaki przekazujesz contentString był dla mnie przydatny, dzięki.
ownking
4

odrobinę późno, ale udało mi się otworzyć tylko jedno okno informacyjne, ustawiając je jako zmienną globalną.

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

następnie wewnątrz listnera

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

infowindow.open(map, this);
user2827958
źródło
1
U mnie działa świetnie :)
lumos
4

Zadeklaruj globar var selectedInfoWindow;i użyj go do zatrzymania otwartego okna informacyjnego:

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
źródło
0

Musisz śledzić poprzedni obiekt InfoWindow i wywoływać na nim metodę close , gdy obsługujesz zdarzenie click nowego znacznika .

Uwaga: nie jest konieczne wywoływanie funkcji close na udostępnionym obiekcie okna informacyjnego, wywołanie open z innym znacznikiem automatycznie zamknie oryginał. Zobacz odpowiedź Daniela po szczegóły.

RedBlueThing
źródło
Wiem, że to stara odpowiedź, a interfejs API v3 był wówczas niejasny ... Ale w rzeczywistości nie ma potrzeby wywoływania close()metody, jeśli InfoWindowużywany jest pojedynczy obiekt. Zamknie się automatycznie, jeśli open()metoda zostanie ponownie wywołana na tym samym obiekcie.
Daniel Vassallo
@ daniel-vassallo Dzięki za notatkę :) Odpowiednio zagłosowałem za Twoją odpowiedź, myślę, że jest najbardziej przydatna.
RedBlueThing
0

Zasadniczo potrzebujesz jednej funkcji, która zachowuje odniesienie do one new InfoBox()=> deleguje zdarzenie onclick. Tworząc swoje markery (w pętli) użyjbindInfoBox(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 infoBoxjest przypisywany asynchronicznie i przechowywany w pamięci. Za każdym razem, gdy wywołasz bindInfoBox()funkcję return, zostanie wywołana funkcja return. Przydaje się również do zaliczenia infoBoxOptionstylko raz!

W moim przykładzie musiałem dodać dodatkowy parametr do parametru, mapponieważ moja inicjalizacja jest opóźniona przez zdarzenia kart.

InfoBoxOptions

Tim Vermaelen
źródło
0

Oto rozwiązanie, które nie wymaga tworzenia tylko jednego pliku infoWindow, aby go ponownie użyć. Możesz kontynuować tworzenie wielu okien infoWindows, jedyne, czego potrzebujesz, to zbudowanie funkcji closeAllInfoWindows i wywołanie jej przed otwarciem nowego okna informacyjnego. Tak więc, zachowując swój kod, wystarczy:

  1. Utwórz globalną tablicę do przechowywania wszystkich informacjiWindows

    var infoWindows = [];
    
  2. Przechowuj każde nowe infoWindow w tablicy, zaraz po infoWindow = new ...

    infoWindows.push(infoWindow);
    
  3. Utwórz funkcję closeAllInfoWindows

    function closeAllInfoWindows() {
        for (var i=0;i<infoWindows.length;i++) {
            infoWindows[i].close();
        }
    }
    
  4. W swoim kodzie wywołaj metodę closeAllInfoWindows () tuż przed otwarciem infoWindow.

Pozdrowienia,

Jortx
źródło
-1

Rozwiązałem to w ten sposób:

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
źródło
-4

W Mapach Google możesz mieć otwarte tylko jedno okno informacyjne. Więc jeśli otworzysz nowe okno, drugie zamknie się automatycznie.

Kimmo Puputti
źródło
2
to nie w porządku, mogę otworzyć aż 20 okien informacyjnych na mojej mapie. to jest v3 przy okazji.
leo
OK, dzięki za poprawienie. Nie wiedziałem, że zmieniło się to w wersji 3.
Kimmo Puputti