it-swarm.com.de

Google Maps API v3 fügt jeder Markierung ein InfoWindow hinzu

HINWEIS: Ich verwende Version 3 der Google Maps API

Ich versuche, zu jeder Markierung, die ich auf der Karte platziere, ein Infofenster hinzuzufügen. Zur Zeit mache ich das mit dem folgenden Code:

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

Das Problem ist, wenn ich auf eine Markierung klicke, wird nur das Infofenster für die zuletzt hinzugefügte Markierung angezeigt. Nur um klar zu sein, erscheint das Infofenster neben der letzten Markierung und nicht der angeklickten Markierung. Ich kann mir vorstellen, dass mein Problem im addListener-Bereich liegt, aber ich bin nicht postitiv. Irgendwelche Ideen?

44
blcArmadillo

Sie haben ein sehr häufiges Abschlussproblem in der for in-Schleife:

In einem Abschluss eingeschlossene Variablen verwenden dieselbe Umgebung, dh, wenn der Aufruf der Variable click von der Variable addListener aufgerufen wird, hat die Schleife ihren Lauf und die Variable info zeigt auf das letzte Objekt, das das letzte Objekt ist InfoWindow erstellt.

In diesem Fall besteht eine einfache Möglichkeit zur Lösung dieses Problems darin, Ihr Marker-Objekt mit der InfoWindow zu erweitern:

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

Dies kann ein heikles Thema sein, wenn Sie nicht wissen, wie Schließungen funktionieren. Sie können den folgenden Mozilla-Artikel für eine kurze Einführung lesen:

Beachten Sie auch, dass die v3-API mehrere InfoWindows auf der Karte zulässt. Wenn Sie nur eine InfoWindow zu diesem Zeitpunkt anzeigen möchten, sollten Sie stattdessen ein einzelnes InfoWindow-Objekt verwenden und es dann öffnen und seinen Inhalt ändern, wenn Sie auf die Markierung klicken ( Source ).

79
Daniel Vassallo

Sie können this in event verwenden: 

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.
});
35
ostapische

Der add_marker hat immer noch ein Schließungsproblem, da er die Marker-Variable außerhalb des Bereichs google.maps.event.addListener verwendet.

Eine bessere Implementierung wäre:

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

Ich habe auch die Karte aus der Markierung verwendet. Auf diese Weise müssen Sie das Google-Kartenobjekt nicht übergeben. Sie möchten wahrscheinlich die Karte verwenden, zu der die Markierung ohnehin gehört.

9
ceasaro

Hallo alle miteinander. Ich weiß nicht, ob dies die optimale Lösung ist, aber ich dachte, ich würde sie hier posten, um den Leuten hoffentlich in Zukunft zu helfen. Bitte kommentieren Sie, wenn Sie etwas sehen, das geändert werden soll.

Meine for loops ist jetzt:

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

Und add_marker ist definiert als:

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

Sie können info_window.close () jederzeit zum Deaktivieren von info_window verwenden. Hoffe das hilft jemandem.

1
blcArmadillo

erstellen Sie für Earth-Plugin-APIs die Sprechblase außerhalb Ihrer Schleife und übergeben Sie Ihren Zähler an die Funktion, um eindeutige Inhalte für jede Ortsmarke zu erhalten!

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
Al-Chalabee

In meinem Fall (Verwendung von Javascript in Razor) Dies funktionierte perfekt in einer Foreach-Schleife 

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

Ich hatte ein ähnliches Problem. Wenn Sie lediglich Informationen anzeigen möchten, wenn Sie den Mauszeiger über einen Marker bewegen, anstatt darauf zu klicken, habe ich festgestellt, dass eine gute Alternative zur Verwendung eines Infofensters darin besteht, einen Titel auf dem Marker zu setzen. Immer wenn Sie den Mauszeiger über die Markierung bewegen, wird der Titel wie ein ALT-Tag angezeigt. 'marker.setTitle (' Marker '+ id);' Damit entfällt die Notwendigkeit, einen Listener für den Marker zu erstellen

0
cormacio100

Die einzige Möglichkeit, dies endlich zu erreichen, war das Erstellen eines Arrays in JavaScript. Die Array-Elemente referenzieren die verschiedenen Infofenster (für jede Markierung auf der Karte wird ein Infofenster erstellt). Jedes Arrayelement enthält den eindeutigen Text für die entsprechende Kartenmarkierung. Ich habe das JavaScript-Ereignis für jedes Infofenster basierend auf dem Array-Element definiert. Wenn das Ereignis ausgelöst wird, verwende ich das Schlüsselwort "this", um auf das Array-Element zu verweisen, um auf den entsprechenden anzuzeigenden Wert zu verweisen.

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
John Doe

Versuche dies:

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
JochenJung