Проблема закрытия с маркерами Listener и Google Maps

Я хочу добавить событие Listener к каждому сгенерированному маркеру, чтобы при нажатии маркера вы перенаправлялись на URL-адрес постоянной ссылки. С приведенным ниже кодом значение постоянной ссылки одинаково для каждого маркера (получается последнее значение). Я читал о проблемах с закрытием, и, похоже, это то, что у меня есть. Я действительно не понимаю примеры, на которые я смотрел, хотя.

Может ли кто-нибудь взглянуть на мой код и указать мне правильное направление? Любая помощь приветствуется!

downloadUrl("http://localhost/map/generatexml.php", function(data) {
            var xml = parseXml(data);
            var markers = xml.documentElement.getElementsByTagName("marker");
            for (var i = 0; i < markers.length; i++) {
              var permalink = markers[i].getAttribute("permalink");
              var point = new google.maps.LatLng(
                  parseFloat(markers[i].getAttribute("lat")),
                  parseFloat(markers[i].getAttribute("lng")));
              var marker = new google.maps.Marker({map: map,position: point,icon: icon.icon,shadow: icon.shadow,title: name});
              google.maps.event.addListener(marker, 'click', function() {self.location.href = permalink;});
            }

person Daniel Westman    schedule 24.02.2010    source источник
comment
Это один из наиболее распространенных и повторяющихся вопросов о замыканиях с участием циклов, возможных дубликатов: stackoverflow.com/questions/1734749 stackoverflow.com/questions/643542 stackoverflow.com/questions/ 1582634 stackoverflow.com/questions/1331769 stackoverflow.com/questions/1552941 stackoverflow.com/questions/750486 stackoverflow.com/questions/933343 stackoverflow.com/questions/1579978 stackoverflow.com/questions/1413916 стек erflow.com/questions/2314175   -  person Christian C. Salvadó    schedule 24.02.2010
comment
Извините, что задаю еще один заключительный вопрос, но я просмотрел кучу более ранних ответов и просто не смог заставить его работать. Но спасибо за ссылки!   -  person Daniel Westman    schedule 25.02.2010


Ответы (3)


Попробуй это:

for (var i = 0; i < markers.length; ++i) {
  // ... like what you have already ...
  (function(permalink) {
    google.maps.event.addListener(marker, 'click', function() {self.location.href = permalink;});
  })(permalink);
}

Создавая новую лексическую область видимости с копией значения «постоянная ссылка» на каждой итерации, ваши обработчики должны работать лучше.

person Pointy    schedule 24.02.2010
comment
Почему я изо всех сил пытался придумать такое простое решение? я ревную - person Bob; 24.02.2010
comment
Спасибо, Пойнти, я часами пытался заставить это работать. Ваш код сработал, и вы мой герой! - person Daniel Westman; 25.02.2010

JavaScript имеет только область действия функции, поэтому, когда вы объявляете var в середине цикла for, вы фактически объявляете их только один раз для всей функции. Первое, что вы должны сделать, это вывести все объявления var наверх, чтобы понять, что происходит:

downloadUrl("http://localhost/map/generatexml.php", function(data) {
            var xml = parseXml(data);
            var markers = xml.documentElement.getElementsByTagName("marker");
            var i, permalink, point, marker;
            for (i = 0; i < markers.length; i++) {
              permalink = markers[i].getAttribute("permalink");
              point = new google.maps.LatLng(
                  parseFloat(markers[i].getAttribute("lat")),
                  parseFloat(markers[i].getAttribute("lng")));
              marker = new google.maps.Marker({map: map,position: point,icon: icon.icon,shadow: icon.shadow,title: name});
              google.maps.event.addListener(marker, 'click', function() {self.location.href = permalink;});
            }

Ваша функция клика будет использовать конечное значение постоянной ссылки для каждого события маркера, поскольку постоянная ссылка заменяется новым значением каждый раз, когда цикл for-loop.

Редактировать: Так что да, Пойнти опередил меня в решении вашей проблемы. Но вот вам, по крайней мере, объяснение проблемы

person Bob    schedule 24.02.2010
comment
Спасибо, Боб, за помощь, ты классный :) - person Daniel Westman; 25.02.2010

Мы должны использовать замыкания, чтобы решить эту проблему

Используйте приведенный ниже фрагмент кода, чтобы добавить информационное окно к маркеру.

function AddInfoWidnow(marker,message)
{
     var infowindow = new google.maps.InfoWindow({ content: message });

     google.maps.event.addListener(marker, 'click', function() {

     infowindow.open(marker.get('map'), marker);

    }); 

}

Чтобы увидеть рабочий образец, обратитесь здесь

person Durai Amuthan.H    schedule 28.02.2014