Карты Google и их маркеры

У меня есть массив маркеров JSON, который вставляется в карту Google - это работает отлично.

У меня также есть информационные окна, связанные с каждым из этих маркеров - они также работают нормально.

Однако когда я щелкаю маркер (в любом браузере), информационное окно появляется только над последним добавленным маркером.

Вот скрипка: http://jsfiddle.net/neuroflux/8WDwn/10/ и вот мой цикл:

for (var a = 0; a < dealer_markers.length; a++) {
    var tmpLat = dealer_markers[a].lat;
    var tmpLng = dealer_markers[a].lng;
    var tmpName = dealer_markers[a].name;
    var tmpAdr = dealer_markers[a].adr;
    var tmpTel = dealer_markers[a].pc;
    var tmpPc = dealer_markers[a].tel;

    contentString[a] = '<div id="bg"><h2 class="title">'+tmpName+'</h2><h3 class="address">'+tmpAdr+'</h3><h3 class="pc">'+tmpPc+'</h3><h3 class="telephone">'+tmpTel+'</h3></div>';
    var content = contentString[a];

    dealer[a] = new google.maps.LatLng(tmpLat,tmpLng);

    deal = dealer[a];

    marker[a] = new google.maps.Marker({ 
        map:map,
        position: deal,
        icon:'dealer.png',
        title: "|"+new google.maps.LatLng(dealer[a].Ja,dealer[a].Ka)
    });

    lat = marker[a].position.Ja;
    lng = marker[a].position.Ka;

    compositeLatLng = new google.maps.LatLng(lat,lng);
    mark = marker[a];


    google.maps.event.addListener(mark, 'click', function(a) {
        if (mark.infowindow) {
            mark.infowindow.close();
        }

        mark.infowindow = new google.maps.InfoWindow({ 
            content: contentString[marker.indexOf(this)]
        });

        mark.infowindow.open(map,mark);
    });
}

2 ответа

Решение

Как я уже говорил в своем комментарии, вы можете использовать замыкание для обхода проблемы. Вот демо. Я создал функцию-обертку, которая:

  1. создает маркер
  2. опционально прикрепляет обработчик onclick

Внутри этого обработчика:

  1. он прикрепляет пустое информационное окно к карте (при необходимости)
  2. оно скрывает это окно, меняет его содержимое и снова показывает его над маркером (логика заимствована отсюда)

function _newGoogleMapsMarker(param) {
    var r = new google.maps.Marker({
        map: param._map,
        position: new google.maps.LatLng(param._lat, param._lng),
        title: param._head
    });
    if (param._data) {
        google.maps.event.addListener(r, 'click', function() {
            // this -> the marker on which the onclick event is being attached
            if (!this.getMap()._infoWindow) {
                this.getMap()._infoWindow = new google.maps.InfoWindow();
            }
            this.getMap()._infoWindow.close();
            this.getMap()._infoWindow.setContent(param._data);
            this.getMap()._infoWindow.open(this.getMap(), this);
        });
    }
    return r;
}


for (var a = 0; a < dealer_markers.length; a++) {
    .
    .
    .
    var marker = _newGoogleMapsMarker({
        _map: map,
        _lat: tmpLat,
        _lng: tmpLng,
        _head: '|' + new google.maps.LatLng(tmpLat, tmpLng),
        _data: '...'
    });
}

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

Также не рекомендуется создавать функции в циклах, поэтому я бы переписал это так:

var map = null // your map created here

var infowindow = null;

var itemClick = function(a) {
    if (this.infowindow) {
        this.infowindow.close();
    }

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

    this.infowindow.open(this.map, a);

}

for (var a = 0; a < dealer_markers.length; a++) {

    ///  Other code.....

    google.maps.event.addListener(mark, 'click', itemClick);
}
Другие вопросы по тегам