Google Maps API v3'te yalnızca bir InfoWindow açık olsun


85

Google Haritamda yalnızca bir InfoWindow'un açık olması gerekiyor. Yeni bir tane açmadan önce diğer tüm InfoWindows'u kapatmam gerekiyor.

Biri bana bunun nasıl yapılacağını gösterebilir mi?


Ne denedin
IgniteCoders

Yanıtlar:


152

Tek bir InfoWindownesne oluşturmanız , ona bir referans tutmanız ve tüm işaretçiler için eğer yeniden kullanmanız gerekir. Google Maps API Dokümanlarından Alıntı :

Aynı anda yalnızca bir bilgi penceresinin görüntülenmesini istiyorsanız (Google Haritalar'daki davranış gibi), harita olayları (kullanıcı tıklamaları gibi) üzerine farklı konumlara veya işaretleyicilere yeniden atayabileceğiniz yalnızca bir bilgi penceresi oluşturmanız gerekir.

Bu nedenle, InfoWindowharitanızı başlattıktan hemen sonra nesneyi oluşturmak ve ardından clickişaretçilerinizin olay işleyicilerini aşağıdaki gibi işlemek isteyebilirsiniz . Diyelim ki adında bir işaretiniz var someMarker:

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

Ardından, yöntemi InfoWindowçağırmanıza gerek kalmadan yeni bir işaretleyiciye tıkladığınızda otomatik olarak kapanmalıdır close().


Bunu ben de yapıyorum, ancak infoWindow'un bir sonraki işaretçide açılması için +1 saniye sürmesi normal mi? bazen hiç açılmıyor. Tam olarak aynı kodu kullanıyorum
MJB

Daniel, harika fikir !! ondan önce manuel olarak senkronize etmeye çalışıyordum, ancak garip javascript hataları gösteriyor (main.js'de "c null" veya (123 aralık dışı 43) gibi).
Victor

31

Bilgi pencerenizi, paylaşabilmek için kapsamın dışında oluşturun.

İşte basit bir örnek:

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

Teşekkür ederim. "Bunu" kullanmak sorunlarımın çoğunu çözdü. SetContent içinde özel içeriği nasıl kullanacağımı hâlâ anlamıyorum. Örneğin, marker döngümde, "i" değişkenini kullanarak ve onu bir veritabanı nesnesine bağlayarak bir contentHtml değişkeni oluşturuyorum. Bu contentHtml değişkenini dinleyiciye nasıl iletebilirim?
Ryan

Benim durumumda pencere sadece infowindow.open (map, this) içinde "this" kullandığımda açılıyor; "İşaretçi" yerine. Çözümünüzü paylaştığınız için teşekkürler.
ownking

Bunu ben de yapıyorum, ancak infoWindow'un bir sonraki işaretçide açılması için +1 saniye sürmesi normal mi? bazen hiç açılmıyor. Tam olarak aynı kodu kullanıyorum
MJB

14

Aynı sorunu yaşadım ama en iyi cevap onu tamamen çözmedi, for ifademde yapmam gereken, bunu mevcut işaretçimle ilgili olarak kullanmaktı. Belki bu birine yardımcı olur.

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'i geçme şekliniz benim için yararlı oldu, thx.
26'da sahip olmak

5

biraz geciktim, ancak küresel bir değişken içerisine girerek sadece bir bilgi penceresini açmayı başardım.

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

sonra listenin içinde

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

infowindow.open(map, this);

1
Benim için harika çalışıyor :)
lumos

4

Bir globar bildirin var selectedInfoWindow;ve açık bilgi penceresini tutmak için kullanın:

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

Yeni bir işaretçi üzerinde tıklama olayını işlediğinizde önceki InfoWindow nesnenizi takip etmeniz ve bu nesnede kapatma yöntemini çağırmanız gerekir .

NB Paylaşılan bilgi penceresi nesnesinde close çağrısı yapmak gerekli değildir, farklı bir işaretleyici ile open çağrısı orijinali otomatik olarak kapatacaktır. Ayrıntılar için Daniel'in cevabına bakın.


Bunun eski bir cevap olduğunu biliyorum ve v3 API o sırada belirsizdi ... Ama aslında close()tek bir InfoWindownesne kullanılıyorsa , yöntemi çağırmaya gerek yok . open()Yöntem aynı nesne üzerinde tekrar çağrılırsa otomatik olarak kapanacaktır .
Daniel Vassallo

@ daniel-vassallo Not için teşekkürler :) Cevabınızı buna göre yükselttim, bence en faydalı olanı bu.
RedBlueThing

0

Temel olarak, bir new InfoBox()=> onclick olayına atıfta bulunan bir işlev istersiniz . İşaretçilerinizi oluştururken (bir döngüde) kullanınbindInfoBox(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 infoBoxzaman uyumsuz olarak atanır ve bellekte tutulur. Her bindInfoBox()aradığınızda bunun yerine return işlevi çağrılacaktır. Geçmek için de kullanışlıdırinfoBoxOptionsSadece bir kez !

Örneğimde, mapbaşlatmam sekme olayları nedeniyle geciktiğinden , ek bir parametre eklemek zorunda kaldım .

InfoBoxOptions


0

Yeniden kullanmak için yalnızca bir infoWindow oluşturması gerekmeyen bir çözüm burada. Birçok infoWindows oluşturmaya devam edebilirsiniz, ihtiyacınız olan tek şey bir closeAllInfoWindows işlevi oluşturmak ve yeni bir bilgi penceresi açmadan önce onu çağırmaktır. Dolayısıyla, kodunuzu saklayarak yapmanız gereken tek şey:

  1. Tüm infoWindows'u depolamak için global bir dizi oluşturun

    var infoWindows = [];
    
  2. Her yeni infoWindow'u dizide, infoWindow = new ... 'den hemen sonra depolayın.

    infoWindows.push(infoWindow);
    
  3. CloseAllInfoWindows işlevini oluşturun

    function closeAllInfoWindows() {
        for (var i=0;i<infoWindows.length;i++) {
            infoWindows[i].close();
        }
    }
    
  4. Kodunuzda, infoWindow'u açmadan hemen önce closeAllInfoWindows () öğesini çağırın.

Saygılarımızla,


Çalışır, ancak çok iyi bir çözüm değildir çünkü diziye bilgi pencereleri eklemeye devam edersiniz, bu nedenle aynı bilgi penceresinin birçok oluşumuna sahip bir diziye sahip olma olasılığı vardır.
Wally

-1

Bunu şu şekilde çözdüm:

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

-5

Google Haritalar, yalnızca bir bilgi penceresine sahip olmanıza izin verir. Yani yeni bir pencere açarsanız diğeri otomatik olarak kapanır.


2
bu doğru değil, haritamda 20'ye kadar bilgi penceresi açabilirim. bu v3 btw.
leo

Tamam, düzelttiğiniz için teşekkürler. Sürüm 3'te değiştiğini bilmiyordum.
Kimmo Puputti
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.