Карты Google: автоматическое закрытие открытых InfoWindows?

108

На своем сайте я использую Google Maps API v3 для размещения маркеров домов на карте.

Информационные окна остаются открытыми, если вы явно не щелкнете значок закрытия. Это означает, что у вас может быть открыто 2+ информационных окна одновременно, если вы наведете курсор на маркер карты.

Вопрос : Как сделать так, чтобы открывалось только текущее активное информационное окно, а все остальные информационные окна закрывались? Значит, одновременно будет открыто не более 1 InfoWindow?

Тед
источник
1
Как по мне, лучше создать всего одно информационное окно и обновлять его (его содержимое и т. Д.), Открывать и закрывать и все такое. Но я почти уверен, что этот подход не всегда применим.
Андрей

Ответы:

154

Для InfoWindows есть функция close () . Просто следите за последним открытым окном и вызывайте для него функцию закрытия при создании нового окна.

В этой демонстрации есть функции, которые вы ищете. Я нашел его в демонстрационной галерее Maps API V3 .

Крис Б.
источник
4
Проголосовали за предложение отслеживать только последнее открытое окно. Похоже, ничего страшного, но люди забывают об этих вещах ...
Реми Бретон,
1
Я только что использовал ту же самую технику. Спасибо, Крис. Для меня это было необходимо, потому что я использую массив объектов InfoWindow вместо одного, который циклически просматривает и захватывает соответствующую информацию. У каждого InfoWindow есть своя отдельная обновляемая информация, поэтому я нашел этот метод весьма полезным.
InterfaceGuy
2
ссылка "эта демонстрация" не работает
Брендан Уайтинг
Большое спасибо! Использовал этот подход, и он работал как шарм. Ты исправил мой день. Проголосовали.
Алан Эспине,
64

альтернативное решение для этого с использованием множества информационных окон: сохранить предыдущее открытое информационное окно в переменной, а затем закрыть его при открытии нового окна

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
Простите мою наивность, но что это за база?
поводу
Я не понимаю, почему это не поведение по умолчанию в Google Maps V3 ...
Мистер Вашингтон,
Лучшее и простое решение, которое я нашел до сих пор. Спасибо!
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
    }
);

Это «переместит» информационное окно к каждому нажатому маркеру, по сути, закрыв себя, а затем снова открываясь (и сдвигая, чтобы соответствовать области просмотра) в новом месте. Он изменяет свое содержимое перед открытием, чтобы дать желаемый эффект. Работает для 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
Это действительно элегантно - использование только одного информационного окна и изменение содержимого позволяет избежать необходимости отслеживать / закрывать предыдущее.
Nick F
Это решение действительно очень элегантно и работает как шарм. +1
Себастьян Брайт
9

По этой ссылке http://www.svennerberg.com/2009/09/google-maps-api-3-infowindows/ :

Тео: Самый простой способ сделать это - иметь только один экземпляр объекта InfoWindow, который вы будете использовать снова и снова. Таким образом, когда вы щелкаете по новому маркеру, информационное окно «перемещается» с того места, где оно находится в данный момент, чтобы указывать на новый маркер.

Используйте его метод setContent, чтобы загрузить в него правильный контент.

Кейт Адлер
источник
Я не верю, что это применимо, поскольку я использую API Карт Google v3
Тед,
Кроме того, в статье, на которую вы ссылаетесь, не может быть больше одного маркера,
Тед,
Я использовал одно информационное окно таким же образом для нескольких сайтов. Щелкните один, открытый закрывается автоматически.
Кейт Адлер,
4
Как связать несколько меток с одним InfoWindow?
Тед
7

Объявить переменную для активного окна

var activeInfoWindow; 

и привяжите этот код в прослушивателе маркеров

 marker.addListener('click', function () {
    if (activeInfoWindow) { activeInfoWindow.close();}
    infowindow.open(map, marker);
    activeInfoWindow = infowindow;
});
Хардип Сингх
источник
Спасибо, действительно работает при нажатии в любом месте карты.
Вариндер Сингх Байдван
Ура, чувак, из всех предложений это сработало лучше всего для меня, и это чистый AF.
Мэтью Эллис,
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);
    });
}
MelloG
источник
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
источник
Спасибо, мне нужно было закрыть информационное окно, когда не щелкнул маркер, так что просто на карте
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;  
}); 
П. Нельсон
источник
Что здесь делает [counter]?
Ли
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);
}));
Sai
источник