В Google Maps API v3 должно быть открыто только одно окно InfoWindow.

85

Мне нужно, чтобы на моей карте Google было открыто только одно окно InfoWindow. Мне нужно закрыть все остальные информационные окна, прежде чем открывать новое.

Может кто-нибудь показать мне, как это сделать?

Лео
источник
Что пробовали?
IgniteCoders

Ответы:

151

Вам нужно создать только один InfoWindowобъект, сохранить ссылку на него и повторно использовать его для всех маркеров. Цитата из Документов Google Maps API :

Если вы хотите, чтобы одновременно отображалось только одно информационное окно (как это происходит в Google Maps), вам нужно создать только одно информационное окно, которое вы можете переназначить для разных местоположений или маркеров при событиях карты (например, при нажатии пользователем).

Следовательно, вы можете просто создать InfoWindowобъект сразу после инициализации карты, а затем обработать clickобработчики событий ваших маркеров следующим образом. Допустим, у вас есть маркер под названием someMarker:

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

Затем он InfoWindowдолжен автоматически закрываться, когда вы нажимаете на новый маркер, без необходимости вызывать close()метод.

Даниэль Вассалло
источник
Я тоже так делаю, но нормально ли, что для открытия окна infoWindow на следующем маркере требуется +1 секунда? иногда он вообще не открывается. Я использую тот же код
MJB
Даниэль, отличная идея !! до этого я пытался синхронизировать вручную, но он показывает странные ошибки javascript (например, «c is null» в main.js или что-то вроде (123 вне диапазона 43)).
Виктор
30

Создайте свое информационное окно вне области видимости, чтобы вы могли поделиться им.

Вот простой пример:

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);
  });
}
скарэ
источник
Спасибо. Использование «этого» решило большинство моих проблем. Я до сих пор не понимаю, как использовать пользовательский контент внутри setContent. Например, в цикле маркеров я создаю переменную contentHtml, используя переменную «i», и связываю ее с объектом базы данных. Как я могу передать эту переменную contentHtml слушателю?
Райан
В моем случае окно открывается только тогда, когда я использую "this" в infowindow.open (map, this); Вместо «маркера». Спасибо за то, что поделились своим решением.
ownking 09
Я тоже так делаю, но нормально ли, что для открытия окна infoWindow на следующем маркере требуется +1 секунда? иногда он вообще не открывается. Я использую тот же код
MJB
14

У меня была та же проблема, но лучший ответ не решил ее полностью, что мне нужно было сделать в моем операторе for, так это использовать this, относящийся к моему текущему маркеру. Может это кому-то поможет.

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
То, как вы передаете contentString, было полезно для меня, спасибо.
ownking 09
4

Немного поздно, но мне удалось открыть только одно информационное окно, сделав infowindow глобальной переменной.

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

затем внутри списка

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

infowindow.open(map, this);
user2827958
источник
1
У меня отлично работает :)
lumos
4

Объявите глобар var selectedInfoWindow;и используйте его для удержания открытого информационного окна:

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
источник
0

Вам необходимо отслеживать ваш предыдущий объект InfoWindow и вызывать для него метод close при обработке события щелчка на новом маркере .

NB Нет необходимости вызывать close для объекта общего информационного окна, вызов open с другим маркером автоматически закроет оригинал. Подробнее см . Ответ Даниила .

КрасныйСиний
источник
Я знаю, что это старый ответ, и в то время API v3 был неясным ... Но на самом деле нет необходимости вызывать close()метод, если используется один InfoWindowобъект. Он закроется автоматически, если open()метод снова будет вызван для того же объекта.
Даниэль Вассалло,
@ daniel-vassallo Спасибо за замечание :) Соответственно, я проголосовал за ваш ответ, я думаю, это самый полезный.
RedBlueThing
0

По сути, вам нужна одна функция, которая хранит ссылку на one new InfoBox()=> делегирует событие onclick. При создании маркеров (в цикле) используйте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назначается асинхронно и сохраняется в памяти. Каждый раз, когда вы вызываете bindInfoBox()функцию возврата, будет вызываться вместо нее. Также удобно пройти infoBoxOptionsтолько один раз!

В моем примере мне пришлось добавить дополнительный параметр в, mapпоскольку моя инициализация задерживается событиями вкладки.

InfoBoxOptions

Тим Вермален
источник
0

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

  1. Создайте глобальный массив для хранения всей информации Windows

    var infoWindows = [];
    
  2. Сохраняйте каждое новое окно infoWindow в массиве сразу после infoWindow = new ...

    infoWindows.push(infoWindow);
    
  3. Создайте функцию closeAllInfoWindows

    function closeAllInfoWindows() {
        for (var i=0;i<infoWindows.length;i++) {
            infoWindows[i].close();
        }
    }
    
  4. В своем коде вызовите closeAllInfoWindows () непосредственно перед открытием окна infoWindow.

С Уважением,

Jortx
источник
-1

Решил это так:

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);
Билал Булаич
источник
-4

Карты Google позволяют открывать только одно информационное окно. Итак, если вы откроете новое окно, другое закроется автоматически.

Киммо Пупутти
источник
2
это неправильно, я могу открыть до 20 информационных окон на моей карте. это v3 кстати.
Лев,
Хорошо, спасибо за исправление. Я не знал, что это изменилось в версии 3.
Киммо Пупутти