Google Maps API v3 dodawanie InfoWindow do każdego znacznika

Uwaga: używam v3 Google Maps API

Próbuję dodać okienko informacyjne do każdego znacznika, który umieszczam na mapie. Obecnie robię to z następującym kodem:

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

Problem polega na tym, że po kliknięciu znacznika wyświetla się okno informacji o ostatnim dodanym znaczniku. Również dla jasności okno informacji pojawia się obok ostatniego znacznika, a nie znacznika klikniętego. Wyobrażam sobie, że mój problem jest w części addListener, ale nie jestem postitive. Jakieś pomysły?

Author: Daniel Vassallo, 2010-07-01

10 answers

Masz bardzo powszechny problem zamknięcia W pętli for in:

Zmienne zamknięte w zamknięciu mają to samo środowisko, więc do czasu wywołania wywołania zwrotnego click z addListener pętla będzie miała swój bieg, a zmienna info zostanie wskazana na ostatni obiekt, który stanie się ostatnim utworzonym InfoWindow.

W tym przypadku, jednym z łatwych sposobów rozwiązania tego problemu byłoby powiększenie Marker obiektu o 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);
});

Może to być dość trudny temat, jeśli nie wiesz, jak działają zamknięcia. Możesz zapoznać się z poniższym artykułem Mozilli, aby uzyskać krótkie wprowadzenie:

Należy również pamiętać, że API v3 pozwala na wiele InfoWindow s na mapie. Jeśli chcesz mieć tylko jeden InfoWindow widoczny w tym czasie, powinieneś użyć jednego InfoWindow obiektu, a następnie otworzyć go i zmienić jego zawartość za każdym razem, gdy znacznik jest clicked ( Source ).

 78
Author: Daniel Vassallo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-01 15:17:43

Możesz użyć this w evencie:

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.
});
 34
Author: ostapische,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-10 06:05:40

Add_marker nadal ma problem z zamknięciem, ponieważ używa zmiennej marker poza google.mapy.wydarzenie.zakres addListener.

Lepszą implementacją byłoby:

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

Użyłem również mapy z markera, w ten sposób nie musisz mijać obiektu google map, prawdopodobnie chcesz użyć mapy, do której należy marker.

 9
Author: ceasaro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-27 09:47:56

Cześć wszystkim. Nie wiem, czy jest to optymalne rozwiązanie, ale pomyślałem, że opublikuję je tutaj, aby pomóc ludziom w przyszłości. Proszę skomentować, jeśli zobaczysz coś, co powinno zostać zmienione.

Moje pętle for to teraz:

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

I add_marker definiuje się jako:

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

Możesz użyć info_window.close (), aby wyłączyć info_window w dowolnym momencie. Mam nadzieję, że to komuś pomoże.

 1
Author: blcArmadillo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-01 17:49:32

W przypadku API wtyczek Earth, Utwórz balon poza pętlą i przekaż licznik do funkcji, aby uzyskać unikalną zawartość dla każdego miejsca!

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);
            });
        }
 1
Author: Al-Chalabee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-05 23:39:47

W moim przypadku (używając Javascript Insidde Razor) to działało idealnie wewnątrz pętli Foreach

google.maps.event.addListener(marker, 'click', function() {
    marker.info.open(map, this);
});
 1
Author: Rhibi Hamza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-29 02:50:36

Spróbuj tego:

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
Author: JochenJung,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-01 14:24:31

Miałem bardzo podobny problem ale w ActionScript 3: stos nad przepływem: dynamiczne okno informacyjne API Google Maps problem z zawartością HTML

Próbowałem wyciągnąć unikalne informacje do htmlcontent podpowiedzi z bazy danych i okazało się, że otrzymuję informacje o ostatnim znaczniku, który dodałem w każdym znaczniku.

Zakładając, że nie jest to problem specyficzny dla actionscriptu, rozwiązanie Jochenjunga nie zadziała. Spójrz na rozwiązanie, które zamieściłem w moim problemie i zobacz, czy można go zastosować tutaj. Wydaje się, że jest to poważny problem z API Map.

 0
Author: Peter Hanneman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:29

Jedynym sposobem, w jaki mogłem to w końcu uruchomić, było stworzenie tablicy w JavaScript. Elementy tablicy odnoszą się do różnych okien informacyjnych (dla każdego znacznika na mapie jest tworzone jedno okno informacyjne). Każdy element tablicy zawiera unikalny tekst dla odpowiedniego znacznika mapy. Zdefiniowałem Zdarzenie JavaScript dla każdego okna info na podstawie elementu array. A gdy zdarzenie zostanie wywołane, użyję słowa kluczowego "this", aby odwołać się do elementu tablicy, aby odnieść się do odpowiedniej wartości wyświetlacz.

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);
    });
}
 0
Author: John Doe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-29 21:54:39

Miałem podobny problem. Jeśli wszystko, co chcesz, to jakieś informacje, które mają być wyświetlane po najechaniu kursorem na znacznik, zamiast klikać go, a następnie okazało się, że dobrą alternatywą dla korzystania z okna informacji było ustawienie tytułu na znaczniku. W ten sposób za każdym razem, gdy najedziesz kursorem myszy na znacznik, tytuł będzie wyświetlany jak znacznik ALT. marker.setTitle ('Marker'+id);" Usuwa też potrzebę tworzenia słuchacza dla znacznika

 0
Author: cormacio100,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-22 12:26:44