Карти Google: Автоматично закрити відкриті InfoWindows?


108

На своєму веб-сайті я використовую API Карт Google v3 для розміщення позначок на карті.

InfoWindows залишається відкритим, якщо явно не натиснути значок закриття. Значить, ви можете відкрити 2+ InfoWindows за раз, якщо навести курсор на маркер карти.

Питання : Як зробити так, щоб тільки поточне активне InfoWindow було відкрите, а всі інші InfoWindows були закриті? Значить, одночасно буде відкрито не більше 1 інформаційного вікна?


1
Що стосується мене, то краще створити лише одне інформаційне вікно та оновити його (це вміст тощо), відкрити та закрити і все. Але я впевнений, що такий підхід не завжди застосований.
andrii

Відповіді:


154

Існує функція close () для InfoWindows. Просто слідкуйте за останнім відкритим вікном і викликайте функцію закриття на ньому, коли створюється нове вікно.

Ця демонстрація має функціональні можливості, які ви шукаєте. Я знайшов це в демонстраційній галереї Maps API V3 .


4
Запропоновано запропонувати відстежувати лише останнє відкрите вікно. Схоже, що це без розуму, але люди забувають про ці речі ...
Ремі Бретон

1
Я щойно використовував таку саму техніку. Дякую Крису. Мені це було потрібно, тому що я використовую масив об’єктів InfoWindow замість того, щоб просто перебирати та захоплювати відповідну інформацію. У кожному InfoWindow є своя окрема інформація, що оновлює, тому я вважав цю методику досить корисною.
InterfaceGuy

2
посилання "ця демонстрація" порушена
Брендан Уатінг

Велике спасибі! Використовували такий підхід, і він працював як шарм. Ви зафіксували мій день. Отримано.
Алан Еспінет

64

Альтернативне рішення для цього з використанням багатьох infowindows: збережіть попереднє відкрите infowindow у змінній, а потім закрийте його, коли відкриється нове вікно

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

3
Як ця. Простий для розуміння та втілення в життя
Аамір Африді

6
Пробачте мою наївність, але WTF - це основа?
словазвідси

Я не розумію, чому це не поведінка за замовчуванням у Google Maps V3 ...
Містер Вашингтон,

Найкраще і найпростіше рішення, яке я знайшов поки що. спасибі!
Іртеза Асад

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

Це "перемістить" інформаційне вікно навколо кожного клацається маркера, фактично закрившись, а потім повторно відкрившись (і перемістившись, щоб відповідати вікні перегляду) у новому місці. Він змінює свій вміст перед відкриттям, щоб дати бажаний ефект. Працює для n маркерів.


1
Швидка примітка: повторних дзвінків на infowindow.open () достатньо; вікно спочатку не потрібно закривати.
Ерік Нгуен

3
@Eric, хоча ви технічно правильні, я помітив помилку, яка іноді викликає появу інформаційних вікон у їх останньому місці. Примушуючи закрити перші поразки зазначеного помилка.
Джоел Меллон

22

Моє рішення.

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

3
Це дійсно елегантно - лише використання одного інформаційного вікна та зміна вмісту дозволяє уникнути відстеження / закриття попереднього.
Нік Ф

Це рішення справді дуже елегантне і працює як шарм. +1
Себастьян Брейт

9

За цим посиланням http://www.svennerberg.com/2009/09/google-maps-api-3-infowindows/ :

Teo: Найпростіший спосіб зробити це - мати лише один екземпляр об'єкта InfoWindow, який ви повторно використовуєте знову і знову. Таким чином, коли ви клацаєте новий маркер, інформаційне вікно "переміщується" з того місця, де зараз знаходиться, щоб вказувати на новий маркер.

Використовуйте його метод setContent, щоб завантажити його з правильним вмістом.


Я не вірю, що це стосується, оскільки я використовую API Google Maps v3
Тед

Крім того, стаття, яку ви пов’язали, не демонструє більше 1 маркера
Тед

Я використовував одне інформаційне вікно однаково для кількох сайтів. Клацніть один, відкритий закриється автоматично.
Кіт Адлер

4
Як ви пов'язуєте кілька знаків з одним InfoWindow?
Тед

7

Оголосити змінну для активного вікна

var activeInfoWindow; 

і прив’язати цей код до маркера слухача

 marker.addListener('click', function () {
    if (activeInfoWindow) { activeInfoWindow.close();}
    infowindow.open(map, marker);
    activeInfoWindow = infowindow;
});

Дякую, це дійсно спрацьовує при натисканні будь-якого місця на карті.
Варіндер Сінгх Байдуван

Ура, чувак, з усіх пропозицій, це працювало найкраще для мене і це чисто АФ.
Меттью Елліс

4

Існує простіший спосіб, окрім використання функції close (). якщо ви створите змінну з властивістю InfoWindow, вона автоматично закриється, коли ви відкриєте іншу.

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

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

Дякую, мені потрібно було закрити інформаційне вікно, коли не натиснув маркер, так що просто на карті
VRC

1

Як щодо -

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

    });

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

    });

Тоді ви можете просто навести на нього курсор, і він закриється.


Це цікаве рішення, але воно не відповідає на запитання і не працює на пристроях, що стосуються дотику.
Лі

1

Я зберігав змінну вгорі, щоб відстежувати, яке інформаційне вікно зараз відкрито, див. Нижче.

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

Що тут робить [лічильник]?
Лі

0

Ось що я використав, якщо ви використовуєте багато маркерів у циклі for (Django тут). Ви можете встановити індекс на кожен маркер і встановити його, кожен раз, коли ви відкриваєте вікно. Закриття раніше збереженого індексу:

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 %}

-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);
}));
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.