1

マップベースのアプリケーションを作成しようとしていますが、少し問題があります。使用していた元のコードでは、マーカーごとに個別のインフォウィンドウが追加されていましたが、コンテンツをその場で設定できる単一のインフォウィンドウを使用して取得したいと思います。

ただし、JavaScriptがどのように動作するかについては、まだ少しあいまいなようです。マーカーがクリックされるたびに、インフォウィンドウが最後のマーカーの上にポップアップし、アラートがの最後のエントリのIDを示しているためlocationsです。

短いスニペット、強調表示された問題:

function plotLocations(my_locations) {
    locations = my_locations;
    for(var i=0; i<locations.length; i++) {
        var pos = new google.maps.LatLng(locations[i].loc_lat, locations[i].loc_lng);
        var icon = new google.maps.MarkerImage(
            "http://goo.gl/TQpwU",
            new google.maps.Size(20,32),
            new google.maps.Point(0,0),
            new google.maps.Point(0,32)
        );
        var marker = new google.maps.Marker({
            map: map,
            position: pos,
            animation: google.maps.Animation.DROP,
            icon: icon
        });
// ! -- trouble right here -- ! //
        google.maps.event.addListener(marker, 'click', function() {
            setPopInfo(pos, i);
        });
// ! -- ------------------ -- ! //
    }
}

function setPopInfo(pos, index) {
    pop_info.setPosition(pos);
    pop_info.open(map);
    window.alert(pos+"::"+index);
}

私のコードの残りのほとんど:

var map;
var mapBounds;
var locations;
var pop_info;

$(document).ready(init);

function init() {
    var mapOptions = {
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
    pop_info = new google.maps.InfoWindow({
        content: "I'm not populated!",
        size: new google.maps.Size(100,25)
    });
    google.maps.event.addListener(map, 'bounds_changed', function() {
        queryLocations(map.getBounds());
    });

    prepareGeolocation();
    doGeolocation();
}

function queryLocations(bounds) {
    jQuery.ajax({
        url: 'http://mydomain.com/myapp/test2.php',
        data: bounds.toString(),
        dataType: 'json',
        success: addLocations
    });
}

function addLocations(new_locations) {
    document.getElementById('footer').innerHTML = new_locations;
    plotLocations(new_locations);
}

単一のInfoWindowについての私の理由は、数百のマーカーとInfoWindowsが作成されると、パフォーマンスが低下する可能性があるということです。私がやろうとしていることは実行可能/推奨されますか?

4

1 に答える 1

7

この問題は、ループ内でイベントリスナーコールバック関数を定義しているために発生します。クロージャは、定義時にデータのコピーにバインドするのではなく、動的にコンテキストを参照するため、、、、の同じ値にすべてバインドされる多数の関数を効果的に作成しましlocations.lengthた。ループが終了しました。markerposi

addListenerこれを回避するには、次のように、ループの本体の外側を呼び出す関数を作成します。

function plotLocations (my_locations) {
    locations = my_locations;
    for(var i=0; i<locations.length; i++) {
        var pos = new google.maps.LatLng(locations[i].loc_lat, locations[i].loc_lng);
        var icon = new google.maps.MarkerImage(
            "http://goo.gl/TQpwU",
            new google.maps.Size(20,32),
            new google.maps.Point(0,0),
            new google.maps.Point(0,32)
        );
        var marker = new google.maps.Marker({
            map: map,
            position: pos,
            animation: google.maps.Animation.DROP,
            icon: icon
        });
        bindEvent(marker, pos, i);
    }
}

function bindEvent (marker, pos, i) {
    google.maps.event.addListener(marker, 'click', function() {
        setPopInfo(pos, i);
    });
}
于 2013-01-15T00:37:53.777 に答える