Mapy Google: Automatyczne zamykanie otwartych okien InfoWindows?

108

W mojej witrynie używam Google Maps API v3 do umieszczania znaczników domów na mapie.

Okno InfoWindows pozostanie otwarte, chyba że wyraźnie klikniesz ikonę zamykania. Oznacza to, że możesz mieć otwarte 2+ okna InfoWindows naraz, jeśli najedziesz kursorem na znacznik mapy.

Pytanie : Jak sprawić, by otwarte było tylko bieżące aktywne okno InfoWindow, a wszystkie inne okna były zamknięte? Czyli nie więcej niż 1 okno InfoWindow będzie otwarte jednocześnie?

Przetrząsać
źródło
1
Jeśli chodzi o mnie, lepiej jest utworzyć tylko jedno okno informacyjne i zaktualizować je (zawartość itd.), Otworzyć, zamknąć i wszystko. Ale jestem prawie pewien, że to podejście nie zawsze ma zastosowanie.
andrii

Odpowiedzi:

154

W InfoWindows istnieje funkcja close () . Po prostu śledź ostatnio otwarte okno i wywołaj w nim funkcję zamykania, gdy zostanie utworzone nowe okno.

To demo ma funkcjonalność, której szukasz. Znalazłem to w galerii demonstracyjnej Maps API V3 .

Chris B.
źródło
4
Głos za sugestią śledzenia tylko ostatnio otwartego okna. Wygląda jak nie myślenia, ale ludzie zapominają te rzeczy ...
Remi Breton
1
Właśnie użyłem dokładnie tej samej techniki. Dzięki Chris. Było to dla mnie konieczne, ponieważ używam tablicy obiektów InfoWindow, a nie tylko jednego, który przełącza i pobiera odpowiednie informacje. Każde okno InfoWindow ma własne, oddzielnie aktualizowane informacje, więc uznałem tę technikę za całkiem przydatną.
InterfaceGuy,
2
link „to demo” jest uszkodzony
Brendan Whiting
Dziękuję Ci bardzo! Użyłem tego podejścia i zadziałało jak urok. Naprawiłeś mój dzień. Głosowano za.
Alan Espinet
64

alternatywne rozwiązanie z użyciem wielu okien infowindow: zapisz poprzednie otwarte okno w zmiennej, a następnie zamknij je po otwarciu nowego okna

var prev_infowindow =false; 
...
base.attachInfo = function(marker, i){
    var infowindow = new google.maps.InfoWindow({
        content: 'yourmarkerinfocontent'
    });

    google.maps.event.addListener(marker, 'click', function(){
        if( prev_infowindow ) {
           prev_infowindow.close();
        }

        prev_infowindow = infowindow;
        infowindow.open(base.map, marker);
    });
}
mikrofon
źródło
3
Jak ten. Prosty do zrozumienia i wdrożenia
Aamir Afridi
6
Wybacz moją naiwność, ale WTF to podstawa?
słowa z
Nie rozumiem, dlaczego nie jest to domyślne zachowanie na mapach Google V3 ...
Mr Washington
Najlepsze i najprostsze rozwiązanie, jakie do tej pory znalazłem. Dziękuję Ci!
Irteza Asad
27
//assuming you have a map called 'map'
var infowindow = new google.maps.InfoWindow();

var latlng1 = new google.maps.LatLng(0,0);
var marker1 = new google.maps.Marker({position:latlng1, map:map});
google.maps.event.addListener(marker1, 'click',
    function(){
        infowindow.close();//hide the infowindow
        infowindow.setContent('Marker #1');//update the content for this marker
        infowindow.open(map, marker1);//"move" the info window to the clicked marker and open it
    }
);
var latlng2 = new google.maps.LatLng(10,10);
var marker2 = new google.maps.Marker({position:latlng2, map:map});
google.maps.event.addListener(marker2, 'click',
    function(){
        infowindow.close();//hide the infowindow
        infowindow.setContent('Marker #2');//update the content for this marker
        infowindow.open(map, marker2);//"move" the info window to the clicked marker and open it
    }
);

Spowoduje to „przeniesienie” okna informacyjnego do każdego klikniętego znacznika, w efekcie jego zamknięcie, a następnie ponowne otwarcie (i przesunięcie w celu dopasowania do widocznego obszaru) w nowej lokalizacji. Zmienia swoją zawartość przed otwarciem, aby uzyskać pożądany efekt. Działa dla znaczników n.

Joel Mellon
źródło
1
Uwaga: wystarczające są wielokrotne wywołania infowindow.open (); okno nie musi być najpierw zamykane.
Eric Nguyen
3
@Eric, chociaż technicznie jesteś poprawny, zauważyłem błąd, który czasami powoduje, że okna informacyjne pojawiają się na ostatniej pozycji. Wymuszenie zamknięcia pierwszych porażek powiedział błąd.
Joel Mellon
22

Moje rozwiązanie.

var map;
var infowindow = new google.maps.InfoWindow();
...
function createMarker(...) {
var marker = new google.maps.Marker({
     ...,
     descrip: infowindowHtmlContent  
});
google.maps.event.addListener(marker, 'click', function() {
    infowindow.setOptions({
        content: this.descrip,
        maxWidth:300
    });
    infowindow.open(map, marker);
});
kaidoj
źródło
3
To naprawdę eleganckie - użycie tylko jednego okna informacyjnego i zmiana treści pozwala uniknąć konieczności śledzenia / zamykania poprzedniego.
Nick F
To rozwiązanie jest rzeczywiście bardzo eleganckie i działa jak urok. +1
Sebastian Breit
9

Z tego linku http://www.svennerberg.com/2009/09/google-maps-api-3-infowindows/ :

Teo: Najłatwiejszym sposobem na to jest posiadanie tylko jednej instancji obiektu InfoWindow, której będziesz wielokrotnie używać. W ten sposób po kliknięciu nowego znacznika infoWindow zostanie „przeniesione” z miejsca, w którym się obecnie znajduje, i wskaże nowy znacznik.

Użyj jego metody setContent, aby załadować go z poprawną zawartością.

Keith Adler
źródło
Nie wierzę, że to ma zastosowanie, ponieważ używam Google Maps v3 API
Ted,
Ponadto artykuł, do którego również dołączyłeś, nie demonstruje więcej niż 1 znacznika
Ted,
Użyłem pojedynczego okna informacyjnego w ten sam sposób dla kilku witryn. Kliknij jeden, otwarty zamknie się automatycznie.
Keith Adler
4
W jaki sposób można powiązać wiele znaków z pojedynczym programem InfoWindow?
Ted
7

Zadeklaruj zmienną dla aktywnego okna

var activeInfoWindow; 

i powiąż ten kod w odbiorniku znaczników

 marker.addListener('click', function () {
    if (activeInfoWindow) { activeInfoWindow.close();}
    infowindow.open(map, marker);
    activeInfoWindow = infowindow;
});
Hardeep Singh
źródło
Dzięki, to naprawdę działa po kliknięciu dowolnego miejsca na mapie.
Varinder Singh Baidwan
Pozdrawiam stary, spośród wszystkich sugestii, to zadziałało najlepiej i jest czystym AF.
Matthew Ellis
4

Jest łatwiejszy sposób niż użycie funkcji close (). jeśli utworzysz zmienną z właściwością InfoWindow, zamknie się ona automatycznie po otwarciu innej.

var info_window;
var map;
var chicago = new google.maps.LatLng(33.84659, -84.35686);

function initialize() {
    var mapOptions = {
        center: chicago,
        zoom: 14,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

    info_window = new google.maps.InfoWindow({
        content: 'loading'
    )};

createLocationOnMap('Location Name 1', new google.maps.LatLng(33.84659, -84.35686), '<p><strong>Location Name 1</strong><br/>Address 1</p>');
createLocationOnMap('Location Name 2', new google.maps.LatLng(33.84625, -84.36212), '<p><strong>Location Name 1</strong><br/>Address 2</p>');

}

function createLocationOnMap(titulo, posicao, conteudo) {            
    var m = new google.maps.Marker({
        map: map,
        animation: google.maps.Animation.DROP,
        title: titulo,
        position: posicao,
        html: conteudo
    });            

    google.maps.event.addListener(m, 'click', function () {                
        info_window.setContent(this.html);
        info_window.open(map, this);
    });
}
MelloG
źródło
1
var map;
var infowindow;
...
function createMarker(...) {
    var marker = new google.maps.Marker({...});
    google.maps.event.addListener(marker, 'click', function() {
        ...
        if (infowindow) {
            infowindow.close();
        };
        infowindow = new google.maps.InfoWindow({
            content: contentString,
            maxWidth: 300
        });
        infowindow.open(map, marker);
    }
...
function initialize() {
    ...
    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
    ...
    google.maps.event.addListener(map, 'click', function(event) {
        if (infowindow) {
            infowindow.close();
        };
        ...
    }
}
DK
źródło
Dzięki, musiałem zamknąć okno informacyjne, gdy nie kliknąłem znacznika, więc tylko na mapie
VRC,
1

Co powiesz na -

google.maps.event.addListener(yourMarker, 'mouseover', function () {
        yourInfoWindow.open(yourMap, yourMarker);

    });

google.maps.event.addListener(yourMarker, 'mouseout', function () {
        yourInfoWindow.open(yourMap, yourMarker);

    });

Następnie możesz po prostu najechać na niego, a sam się zamknie.

Nathan
źródło
To ciekawe obejście, ale nie odpowiada na pytanie i nie działa na urządzeniach obsługujących tylko dotyk.
Lee
1

Zapisałem zmienną u góry, aby śledzić, które okno informacyjne jest obecnie otwarte, patrz poniżej.

var currentInfoWin = null;
google.maps.event.addListener(markers[counter], 'click', function() {      
    if (currentInfoWin !== null) {
        currentInfoWin.close(map, this); 
    }
    this.infoWin.open(map, this); 
    currentInfoWin = this.infoWin;  
}); 
P Nelson
źródło
Co tu robi [counter]?
Lee
0

Oto czego użyłem, jeśli używasz wielu znaczników w pętli for (tutaj Django). Możesz ustawić indeks dla każdego znacznika i ustawiać go za każdym razem, gdy otwierasz okno. Zamknięcie zapisanego wcześniej indeksu:

markers = Array();
infoWindows = Array();
var prev_infowindow =false;
{% for obj in objects %}
var contentString = 'your content'
var infowindow = new google.maps.InfoWindow({
            content: contentString,
          });
var marker = new google.maps.Marker({
               position: {lat: {{ obj.lat }}, lng: {{ obj.lon }}},
               map: map,
               title: '{{ obj.name }}',
               infoWindowIndex : {{ forloop.counter0 }}
          });
google.maps.event.addListener(marker, 'click',
            function(event)
            {
           if( prev_infowindow ) {
               infoWindows[prev_infowindow].close();
                }
                prev_infowindow = this.infoWindowIndex;
                infoWindows[this.infoWindowIndex].open(map, this);
            }
        );

        infoWindows.push(infowindow);
        markers.push(marker);

      {% endfor %}
Josh
źródło
-1
var contentString = "Location: " + results[1].formatted_address;    
google.maps.event.addListener(marker,'click', (function(){ 
    infowindow.close();
    infowindow = new google.maps.InfoWindow({
        content: contentString
    });
    infowindow.open(map, marker);
}));
Sai
źródło