簡體   English   中英

Google Maps API v3將InfoWindow添加到每個標記

[英]Google Maps API v3 adding an InfoWindow to each marker

注意:我正在使用Google Maps API的v3

我正在嘗試為我放在地圖上的每個標記添加一個信息窗口。 目前我正在使用以下代碼執行此操作:

for (var i in tracks[racer_id].data.points) {
    values = tracks[racer_id].data.points[i];                
    point = new google.maps.LatLng(values.lat, values.lng);
    if (values.qst) {
        var marker = new google.maps.Marker({map: map, position: point, clickable: true});
        tracks[racer_id].markers[i] = marker;
        var info = new google.maps.InfoWindow({
            content: '<b>Speed:</b> ' + values.inst + ' knots'
        });
        tracks[racer_id].info[i] = info;
        google.maps.event.addListener(marker, 'click', function() {
            info.open(map, marker);
        });
    }
    track_coordinates.push(point);
    bd.extend(point);
}

問題是,當我點擊一個標記時,它只顯示添加的最后一個標記的信息窗口。 另外要清楚的是,信息窗口出現在最后一個標記旁邊,而不是單擊標記。 我想我的問題是在addListener部分,但不是postitive。 有任何想法嗎?

你在for in循環中遇到了一個非常常見的閉包問題

封閉在閉包中的變量共享相同的單個環境,因此當調用addListenerclick回調時,循環將運行其路徑並且info變量將指向最后一個對象,這恰好是最后一個InfoWindow創建了。

在這種情況下,解決此問題的一種簡單方法是使用InfoWindow擴充Marker對象:

var marker = new google.maps.Marker({map: map, position: point, clickable: true});

marker.info = new google.maps.InfoWindow({
  content: '<b>Speed:</b> ' + values.inst + ' knots'
});

google.maps.event.addListener(marker, 'click', function() {
  marker.info.open(map, marker);
});

如果您不熟悉閉包的工作方式,這可能是一個非常棘手的主題。 您可以查看以下Mozilla文章以獲得簡要介紹:

另請注意,v3 API允許在地圖上顯示多個InfoWindow 如果您打算當時只有一個InfoWindow可見,則應該使用單個InfoWindow對象,然后在單擊標記時打開它並更改其內容( Source )。

你可以在事件中使用this

google.maps.event.addListener(marker, 'click', function() {  
    // this = marker
    var marker_map = this.getMap();
    this.info.open(marker_map);
    // this.info.open(marker_map, this);
    // Note: If you call open() without passing a marker, the InfoWindow will use the position specified upon construction through the InfoWindowOptions object literal.
});

add_marker仍然存在閉包問題,因為它使用google.maps.event.addListener范圍之外的標記變量。

更好的實施方式是:

function add_marker(racer_id, point, note) {
    var marker = new google.maps.Marker({map: map, position: point, clickable: true});
    marker.note = note;
    google.maps.event.addListener(marker, 'click', function() {
        info_window.content = this.note;
        info_window.open(this.getMap(), this);
    });
    return marker;
}

我也使用了標記中的地圖,這樣你就不需要傳遞谷歌地圖對象,你可能想要使用標記所屬的地圖。

對於地球插件API,在循環外創建氣球並將計數器傳遞給函數以獲取每個地標的唯一內容!

function createBalloon(placemark, i, event) {
            var p = placemark;
            var j = i;
            google.earth.addEventListener(p, 'click', function (event) {
                    // prevent the default balloon from popping up
                    event.preventDefault();
                    var balloon = ge.createHtmlStringBalloon('');
                    balloon.setFeature(event.getTarget());

                    balloon.setContentString('iframePath#' + j);

                    ge.setBalloon(balloon);
            });
        }

嘿大家。 我不知道這是否是最佳解決方案,但我想我會在這里發布,希望將來可以幫助別人。 如果您發現任何應該更改的內容,請發表評論。

我的for循環現在是:

for (var i in tracks[racer_id].data.points) {
    values = tracks[racer_id].data.points[i];                
    point = new google.maps.LatLng(values.lat, values.lng);
    if (values.qst) {
        tracks[racer_id].markers[i] = add_marker(racer_id, point, '<b>Speed:</b> ' + values.inst + ' knots<br /><b>Invalid:</b> <input type="button" value="Yes" /> <input type="button" value="No" />');
    }
    track_coordinates.push(point);
    bd.extend(point);
}

add_marker定義為:

var info_window = new google.maps.InfoWindow({content: ''});

function add_marker(racer_id, point, note) {
    var marker = new google.maps.Marker({map: map, position: point, clickable: true});
    marker.note = note;
    google.maps.event.addListener(marker, 'click', function() {
        info_window.content = marker.note;
        info_window.open(map, marker);
    });
    return marker;
}

您可以隨時使用info_window.close()關閉info_window。 希望這有助於某人。

在我的情況下(使用Javascript insidde Razor)這在Foreach循環中完美地工作

google.maps.event.addListener(marker, 'click', function() {
    marker.info.open(map, this);
});

我最終能夠使用它的唯一方法是在JavaScript中創建一個數組。 數組元素引用各種信息窗口(為地圖上的每個標記創建一個信息窗口)。 每個數組元素都包含適當的地圖標記的唯一文本。 我基於數組元素為每個信息窗口定義了JavaScript事件。 當事件觸發時,我使用“this”關鍵字來引用數組元素以引用要顯示的適當值。

var map = new google.maps.Map(document.getElementById('map-div'), mapOptions);
zipcircle = [];
for (var zip in zipmap) {
    var circleoptions = {
        strokeOpacity: 0.8,
        strokeWeight: 1,
        fillOpacity: 0.35,
        map: map,
        center: zipmap[zip].center,
        radius: 100
    };
    zipcircle[zipmap[zip].zipkey] = new google.maps.Circle(circleoptions);
    zipcircle[zipmap[zip].zipkey].infowindowtext = zipmap[zip].popuptext;
    zipcircle[zipmap[zip].zipkey].infowindow = new google.maps.InfoWindow();
    google.maps.event.addListener(zipcircle[zipmap[zip].zipkey], 'click', function() {
        this.infowindow.setContent(this.infowindowtext);
        this.infowindow.open(map, this);
    });
}

我遇到了類似的問題。 如果你想要的只是當你將鼠標懸停在標記上而不是點擊它時顯示某些信息,那么我發現使用信息窗口的一個很好的替代方法是在標記上設置標題。 這樣,只要將鼠標懸停在標記上,標題就會顯示為ALT標記。 'marker.setTitle('Marker'+ id);' 它也不需要為標記創建一個監聽器

試試這個:

for (var i in tracks[racer_id].data.points) {
    values = tracks[racer_id].data.points[i];                
    point = new google.maps.LatLng(values.lat, values.lng);
    if (values.qst) {
        var marker = new google.maps.Marker({map: map, position: point, clickable: true});
        tracks[racer_id].markers[i] = marker;
        var info = new google.maps.InfoWindow({
            content: '<b>Speed:</b> ' + values.inst + ' knots'
        });
        tracks[racer_id].info[i] = info;
        google.maps.event.addListener(tracks[racer_id].markers[i], 'click', function() {
            tracks[racer_id].info[i].open(map, tracks[racer_id].markers[i]);
        });
    }
    track_coordinates.push(point);
    bd.extend(point);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM