Информационное окно Google Maps отображается с неправильным маркером

#javascript #jquery #google-maps #google-maps-markers

#javascript #jquery #google-карты #google-карты-маркеры

Вопрос:

У меня есть фрагмент кода javascript, где я создаю маркеры и прикрепляю к ним информационные окна, вот так:

 for (var i = 0; i < 8; i  ) {
    var marker = new google.maps.Marker({
       map: map,
       position: new google.maps.LatLng(lat[i], lng[i]),
       icon: '/static/images/iconsets/gmap/iconb'   (i 1)   '.png',
    });
    var infowindow = new google.maps.InfoWindow({
        content: 'test string'
    });
    google.maps.event.addListener(marker, 'click', function() {
        infowindow.open(map,marker);
    });
}
  

Но когда я нажимаю на один из маркеров, информационное окно всегда отображается только на одном маркере. Что я делаю не так?

Ответ №1:

Существует очень простое решение вашей проблемы, которое заключается в том, чтобы поместить код цикла в функцию. Ваша проблема в том, что вы перезаписываете переменную marker , так что при обращении к ней в событии click используется последняя версия этой переменной, которая является последним добавленным вами маркером.

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

 for (var i = 0; i < 8; i  ) {
    createMarker(i);
}

function createMarker(i) {
    var marker = new google.maps.Marker({
        map: map,
        position: new google.maps.LatLng(lat, lng),
        icon: '/static/images/iconsets/gmap/iconb'   (i 1)   '.png',
    });
    var infowindow = new google.maps.InfoWindow({
        content: 'test string'
    });
    google.maps.event.addListener(marker, 'click', function() {
        infowindow.open(map,marker);
    });
}
  

Комментарии:

1. Спасибо за ваш пост! Но почему каждый новый marker объект не сохраняется в первом случае? Я не понимаю, почему это работает, когда вы помещаете код внутри цикла в отдельную функцию.

2. Вы не против взглянуть на этот пример? Он использует тот же код, что и написанный вами, но вызывает из API. Информационные окна не открываются. jsfiddle.net/b20n4jbg @Herman Schaaf

Ответ №2:

 google.maps.event.addListener(Marker, 'click', function() {
    InfoWindow.open(map, this);
});
  

Вы должны использовать this вместо marker, потому что маркер будет содержать значение последнего размещенного маркера.

Ответ №3:

 for (var i = 0; i < 8; i  ) {
    var marker = new google.maps.Marker({
       map: map,
       position: new google.maps.LatLng(lat[i], lng[i]),
       icon: '/static/images/iconsets/gmap/iconb'   (i 1)   '.png',
       content: 'test string'
    });
    google.maps.event.addListener(marker, 'click', function() {
        new google.maps.InfoWindow({
            content: this.content
        }).open(map, this);
    });
}
  

Комментарии:

1. Не могли бы вы добавить некоторый контекст к вашему ответу, пожалуйста, т. Е. Как это помогает спрашивающему? 🙂

2. Я поддержал это 1 час назад, но при тестировании с другим контентом это открывает информационное окно несколько раз, так что мне это все-таки не помогло, извините.

Ответ №4:

В качестве новой опции, которая была недоступна 7 лет назад:

все современные браузеры (то есть все браузеры, поддерживающие ECMAScript 6) поддерживают переменные с блочной областью видимости, которые определяются с помощью let инструкции. let инициализирует переменную внутри заданной области видимости, например, внутри цикла, тогда как var определяет переменные на глобальном или функциональном уровне. В вашем случае замена var на let гарантирует, что каждый маркер правильно инициализирован как новая переменная:

 for (var i = 0; i < 8; i  ) {
    let marker = new google.maps.Marker({
       map: map,
       position: new google.maps.LatLng(lat[i], lng[i]),
       icon: '/static/images/iconsets/gmap/iconb'   (i 1)   '.png',
    });
    let infowindow = new google.maps.InfoWindow({
        content: 'test string'
    });
    google.maps.event.addListener(marker, 'click', function() {
        infowindow.open(map,marker);
    });
}
  

Ответ №5:

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

         // Create a marker for each place.
         marker = new google.maps.Marker({
             map: map,
             icon: icon,
             title: place.name,
             animation: google.maps.Animation.DROP,
             position: place.geometry.location
         });
         var infowindow = new google.maps.InfoWindow({
         content:'<div><strong>'   place.name   '</strong><br>'  
            'Place ID: '   place.place_id   '<br>'  
            place.formatted_address   '</div>'
            });
        marker.addListener('click', function() {
        infowindow.open(map, this);
        });
  

Спасибо