Google Maps API v3, добавляющий InfoWindow к каждому маркеру

Примечание: Я использую v3 Google Maps API

Я пытаюсь добавить информационное окно к каждому маркеру, я поставил карту. В настоящее время я делаю это со следующим кодом:

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. Какие-либо идеи?

45
задан Daniel Vassallo 13 July 2010 в 02:23
поделиться

3 ответа

У вас очень распространенная проблема с закрытием в цикле for in :

Переменные, заключенные в замыкание, используют одну и ту же единую среду, поэтому к моменту выполнения обратного вызова click из addListener будет вызывается, цикл завершится, а переменная info останется указывающей на последний объект, который оказывается последнее созданное InfoWindow .

В этом случае один из простых способов решить эту проблему - добавить в объект Marker объект InfoWindow :

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 для краткого введения:

Также имейте в виду, что API v3 позволяет использовать несколько InfoWindow на карте.Если вы хотите, чтобы одновременно отображалось только одно InfoWindow , вам следует вместо этого использовать один объект InfoWindow , а затем открывать его и изменять его содержимое при каждом щелчке по маркеру ( Источник ).

79
ответ дан 26 November 2019 в 20:56
поделиться

Попробуйте следующее:

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);
}
0
ответ дан 26 November 2019 в 20:56
поделиться

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

Мой цикл 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(), чтобы выключить информационное окно в любое время. Надеюсь, это кому-нибудь поможет.

1
ответ дан 26 November 2019 в 20:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: