web-dev-qa-db-fra.com

Ajout de plusieurs marqueurs avec Infowindows (API Google Maps)

J'utilise actuellement le code suivant pour placer plusieurs marqueurs sur une carte Google à l'aide de leur API.

Le problème que je rencontre est dû au fait que plusieurs infowindows ne fonctionnent pas (ne montrant que le dernier).

Il y a beaucoup de questions comme la mienne ici sur SO. En fait, faites-en un tas de questions :-)

Juste un exemple: Essayer de lier plusieurs InfoWindows à plusieurs marqueurs sur une carte Google et échouer

La solution à mon problème est assez simple: il suffit de joindre le listener à une fonction (anonyme).

Cependant, ce que je ne comprends pas, c’est la raison pour laquelle ma solution ne fonctionne pas (sauvegarde des marqueurs et des sous-fenêtres dans des tableaux au lieu d’une seule variable).

    var markers = [];
    var infowindows = [];

    // add shops or malls
    for (var key in data.markers) {
      if (data.markers.hasOwnProperty(key)) {
        infowindows[key] = new google.maps.InfoWindow({
            content: data.markers[key].infowindow
        });

        markers[key] = new google.maps.Marker({
                position: new google.maps.LatLng(data.markers[key].location.lat, data.markers[key].location.lng),
                map: map,
                flat: true,
                title: data.markers[key].name,
                draggable: false
        });
        var iconFile = 'http://maps.google.com/mapfiles/ms/icons/'+marker_color+'-dot.png';
        markers[key].setIcon(iconFile);

        google.maps.event.addListener(markers[key], 'click', function() {
          infowindows[key].open(map, markers[key]);
        });
      }
    }

Alors ... je ne sais pas quoi trouver, comment le faire fonctionner avec une fonction quelconque pour inclure l'auditeur (bien que cela devrait fonctionner, je ne l'ai pas encore testé, mais ça le sera), mais je veux savoir pourquoi ne fonctionnerait pas si j'ajoutais les marqueurs et les infowindows aux tableaux.

33
PeeHaa

Javascript a une structure de langage appelée "fermetures". Les fermetures sont des fonctions (telles que la fonction () {} que vous déclarez ci-dessus pour traiter les écouteurs de clic) qui capturent les références à des variables externes.

Il existe de nombreuses ressources qui les expliquent mieux que je ne le peux, que je vous suggère de consulter, mais voici ma meilleure tentative:

Dans ce bloc ici:

    google.maps.event.addListener(markers[key], 'click', function() {
      infowindows[key].open(map, markers[key]);
    });

Comme "clé" est déjà défini en tant que variable externe, la fonction capturera une référence à cette variable. Alors où attendez-vous:

infowindows["helloworld"]

Javascript interprétera plutôt ceci comme:

infowindows[reference to key]

Lorsque vous cliquez sur un marqueur, la "référence à la clé" est affichée pour voir quelle est la valeur actuelle de la clé. Parce que cela n'arrivera probablement pas avant la fin de votre boucle, key sera égal à la dernière clé de votre objet data.markers. Et il sera égal à cette valeur pour CHAQUE écouteur de clics que vous avez ajouté.

La solution, comme vous le soulignez, consiste à envelopper cette fonction dans une fonction anonyme pour que Javascript évalue la valeur de "clé" au moment de l'ajout du listener.

  google.maps.event.addListener(markers[key], 'click', function(innerKey) {
      return function() {
          infowindows[innerKey].open(map, markers[innerKey]);
      }
    }(key));
62
plexer

Cela fonctionne bien pour moi! Ajoutez simplement une nouvelle propriété à l’objet marqueur, cette propriété contient l’objet infowindow.

var mytext = 'Infowindow contents in HTML'
var myinfowindow = new google.maps.InfoWindow({
    content: mytext
});

var marker = new google.maps.Marker({
    position: mypos,
    map: mymap,
    icon: myicon,
    title: mytitle,
    infowindow: myinfowindow
});

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

});
54
Tekbreak

Il existe un moyen légèrement plus simple pour y parvenir. vous pouvez ajouter un attribut personnalisé à votre marqueur (l'index de la fenêtre d'information) et vous y référer dans la fonction de rappel. Exemple ci-dessous:

    markers = Array();
    infoWindows = Array();

    for(var i in earthquakes)
    {
        var location = new google.maps.LatLng(earthquakes[i].geolat, earthquakes[i].geolong);
        var marker = new google.maps.Marker({
            position : location,
            map : map,
            animation : google.maps.Animation.DROP,
            infoWindowIndex : i //<---Thats the extra attribute
        });
        var content = "<h3>" + earthquakes[i].title + "<h3>" +
                "<a data-ajax='false' target='_blank' href='" + earthquakes[i].link + "'>Link to shakemap.</a>";
        var infoWindow = new google.maps.InfoWindow({
            content : content
        });

        google.maps.event.addListener(marker, 'click', 
            function(event)
            {
                map.panTo(event.latLng);
                map.setZoom(5);
                infoWindows[this.infoWindowIndex].open(map, this);
            }
        );

        infoWindows.Push(infoWindow);
        markers.Push(marker);
    }
19
Antoine Campbell

Ceci on est une très bonne explication avec la solution avec la page de démonstration.

Ceci est la page de démonstration.

8
syant
    function addMarker(Latlng){ 
       marker = new google.maps.Marker({
            position: Latlng,
            icon:"myicon.jpg",
            map: map,
            animation: google.maps.Animation.DROP,
            title:"My tooltip"
        });

        //add marker
        marker.setMap(map);

        contentString = "<h1>Hello World</h1>";

        marker.infowindow = new google.maps.InfoWindow({
            content: contentString
        });

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

    addMarker(some_lat_lang_value);
2
sidarcy

je vais utiliser la fermeture:

(function(infowindow, marker){google.maps.event.addListener(marker, 'click', function() {
  infowindow.open(map, marker);
});})(infowindow, marker)
1
Sagiv Ofek
var infowindow = null;
infowindow = new google.maps.InfoWindow({
  content: "loading..."
});
for (i = 0; i < data.dbreturn.length; i++) { 
  var latilongi = data.dbreturn[i].mapa.split(',');
  var mapinha =  {lat: parseFloat(latilongi['0']), lng:     parseFloat(latilongi['1'])};
  var marker = new google.maps.Marker({
  position: mapinha,
  html: '<div id="content"><h5 id="firstHeading"     class="firstHeading">'+data.dbreturn[i].nome+'</h5></div>'
});

google.maps.event.addListener(marker, "click", function () {
  infowindow.setContent(this.html);
  infowindow.open(map, this);
});
}
0
Antonio Marques