Добавление нескольких маркеров с помощью информационных окон (Google Maps API) - PullRequest
33 голосов
/ 12 августа 2011

В настоящее время я использую следующий код для размещения нескольких маркеров на карте Google с помощью их API.

Проблема, с которой я сталкиваюсь, заключается в том, что несколько информационных окон не работают (отображается только последнее).

Есть множество вопросов, подобных моему, здесь, на SO.На самом деле это куча вопросов: -)

Просто пример: Попытка привязать несколько InfoWindows к нескольким маркерам на карте Google и ошибка

Решение моегопроблема довольно проста: просто включите прослушиватель щелчков в (анонимную) функцию.

Однако я не понимаю, почему мое решение не работает (сохранение маркеров и информационных окон в массивах вместо одного).переменная).

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

Итак ... Не знаю, как найти решение, как заставить его работать с какой-то функцией, заключающей в себе слушателя (хотя это должно работать, еще не проверял, нобудет), но я хочу знать причину, по которой это не сработает, если я вместо этого добавлю маркеры и информационные окна в массивы.

Ответы [ 7 ]

62 голосов
/ 14 августа 2011

Javascript имеет языковую структуру, которая называется «замыкания». Замыкания - это функции (такие как function () {}, которые вы объявляете выше для работы с прослушивателем кликов), которые захватывают ссылки на внешние переменные.

Существует множество ресурсов, которые объясняют их лучше, чем я, и я предлагаю вам проконсультироваться, но вот моя лучшая попытка:

В этом блоке здесь:

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

Поскольку «ключ» уже определен как внешняя переменная, функция будет захватывать ссылку на эту переменную. Итак, где вы ожидаете:

infowindows["helloworld"]

Javascript вместо этого будет интерпретировать это как:

infowindows[reference to key]

Когда вы нажимаете на маркер, он ищет «ссылку на ключ», чтобы увидеть текущее значение ключа. Поскольку этого, вероятно, не произойдет до тех пор, пока ваш цикл не завершится, ключ будет равен любому последнему ключу в вашем объекте data.markers. И оно будет равно этому значению для КАЖДОГО прослушивателя кликов, который вы добавили.

Решение, как вы указали, заключается в том, чтобы обернуть это в анонимную функцию, чтобы Javascript оценивал значение «ключа» во время добавления прослушивателя щелчков.

  google.maps.event.addListener(markers[key], 'click', function(innerKey) {
      return function() {
          infowindows[innerKey].open(map, markers[innerKey]);
      }
    }(key));
54 голосов
/ 18 октября 2013

Это прекрасно работает для меня!Просто добавьте новое свойство к маркерному объекту, это свойство содержит объект 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);

});
19 голосов
/ 15 июля 2012

Есть немного более простой способ сделать это. Вы можете добавить пользовательский атрибут в свой маркер (индекс информационного окна) и ссылаться на него в функции обратного вызова. Пример ниже:

    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);
    }
8 голосов
/ 20 октября 2012

Это одно довольно хорошее объяснение с решением с демонстрационной страницей.

Это демонстрационная страница.

2 голосов
/ 05 марта 2015
    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);
1 голос
/ 27 февраля 2014

Я буду использовать замыкание:

(function(infowindow, marker){google.maps.event.addListener(marker, 'click', function() {
  infowindow.open(map, marker);
});})(infowindow, marker)
0 голосов
/ 17 мая 2016
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);
});
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...