Подтвердить что ты не робот

Добавление нескольких маркеров с помощью infowindows (API Карт Google)

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

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

На SO есть множество вопросов, таких как мой. На самом деле, это вопрос: -)

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

Решение моей проблемы довольно просто: просто приложите прослушиватель кликов к (анонимной) функции.

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

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

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

4b9b3361

Ответ 1

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

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

В этом блоке:

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

Ответ 2

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

});

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

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

Ответ 6

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

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

Ответ 7

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