Відкрийте лише одне інформаційне вікно в Google Maps API v3


85

На моїй карті Google мені потрібно відкрити лише одне інформаційне вікно. Мені потрібно закрити всі інші InfoWindows, перш ніж відкрити новий.

Хтось може показати мені, як це зробити?


Що ви пробували?
IgniteCoders

Відповіді:


151

Вам потрібно створити лише один InfoWindowоб’єкт, зберегти посилання на нього та повторно використовувати його для всіх маркерів. Цитування з Документів API Карт Google :

Якщо ви хочете, щоб одночасно відображалося лише одне інформаційне вікно (як це відбувається на Картах Google), вам потрібно створити лише одне інформаційне вікно, яке ви можете перепризначити різним місцям або маркерам під час подій на карті (наприклад, кліки користувача).

Тому ви можете просто захотіти створити 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 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); Замість "маркера". Thx для обміну своїм рішенням.
володіння

Я теж це роблю, але чи нормально, що для наступного маркера infoWindow відкривається приблизно за 1 секунду? іноді воно взагалі не відкривається. Я використовую точно такий самий код
MJB

14

У мене була та сама проблема, але найкраща відповідь не вирішила її повністю, що мені потрібно було зробити у своєму заяві for, використовуючи це, що стосується мого поточного маркера. Можливо, це комусь допомагає.

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 був для мене корисним, thx.
володіння

4

трохи пізно, але мені вдалося відкрити лише одне інформаційне вікно, зробивши глобальним змінним maken infowindow.

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

то всередині списку

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

infowindow.open(map, this);

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

0

Вам потрібно відстежувати ваш попередній об’єкт InfoWindow і викликати на ньому метод закриття, коли ви обробляєте подію клацання на новому маркері .

Примітка. Не потрібно викликати закрити об'єкт спільного інформаційного вікна, виклик відкритого з іншим маркером автоматично закриє оригінал. Див відповідь Данила подробиці.


Я знаю, що це стара відповідь, і API v3 на той час був незрозумілим ... Але насправді немає необхідності викликати close()метод, якщо використовується один InfoWindowоб’єкт. Він закриється автоматично, якщо open()метод буде знову викликаний для того самого об'єкта.
Даніель Вассалло,

@ daniel-vassallo Дякую за примітку :) Я відповідно підтримав вашу відповідь, це найбільш корисна, на мою думку.
RedBlueThing

0

В основному вам потрібна одна функція, яка зберігає посилання на одну 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

Ось рішення, для якого не потрібно створювати лише одне infoWindow для його повторного використання. Ви можете продовжувати створювати багато infoWindows, єдине, що вам потрібно, це створити функцію closeAllInfoWindows і викликати її перед тим, як відкрити нове інформаційне вікно. Отже, зберігаючи свій код, вам просто потрібно:

  1. Створіть глобальний масив для зберігання всього infoWindows

    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.

З повагою,


-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 до речі.
Leo

Добре, дякую за виправлення. Я не знав, що це змінилося у версії 3.
Кіммо Пупутті
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.