0

この問題で私を助けてください。作業アドレス変数を使用した次のコードがあります。Infowindow にタイトルを追加しようとしたので、ユーザーがマップ上のマーカーをクリックすると、ポップアップにコンテンツが表示されます。残念ながら、すべてのポップアップで同じタイトルが表示されます。テストしたところ、正しい js 配列ですが、配列から取得した最初のタイトルのみが表示されます。この問題の解決にご協力ください。よろしくお願いします。

<script type="text/javascript" charset="utf-8">    
var map;
var address = < ? php echo json_encode($adr); ? > ;
var titles = < ? php echo json_encode($ttl); ? > ;
var x = 0;
var nbAddresses = address.length;
var geocoder;
var mark;
var contentString = titles[x];

function init() {
    var moptions = {
        zoom: 10,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    }
    map = new google.maps.Map(document.getElementById("map"), moptions);
    geocoder = new google.maps.Geocoder();
    for (var i = 0; i < nbAddresses; i++) {
        geocoder.geocode({
            'address': address[i]
        }, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                mark = new google.maps.Marker({
                    position: results[0].geometry.location,
                    map: map,
                    title: titles[x]
                });
                map.setCenter(results[0].geometry.location);
                x++;
                setInfoWindow();
            }
        });
    }

    function setInfoWindow() {
        google.maps.event.addListener(mark, 'click', function(event) {
            var iwindow = new google.maps.InfoWindow();
            iwindow.setContent(contentString);
            iwindow.open(map, this);
        });
    }
}
window.onload = init;
</script>    
4

2 に答える 2

0

プログラムの開始時に、 contentString を title 配列の最初の要素に設定します

var contentString = titles[x];

次に、setInfoWindow 関数内でこの変数を変更せずに使用します。

次のように、setInfoWindow を contentString パラメータを受け入れるように変更した場合はどうなるでしょうか。

function setInfoWindow(contentString) {...

setInfoWindow を呼び出すときに、タイトルを渡します。

setInfoWindow(title[x]);

この関数を呼び出した後に x をインクリメントするようにしてください。そのため、x++ を setInfoWindow 呼び出しの下に移動します。

EDIT また、いくつかのタイトルが間違ったマーカーに表示されるという奇妙な問題に時々気付くでしょう。これは、一度に複数のジオコードを実行しているため、応答が順不同になる可能性があるためです。

次の変更はそれを修正します。

for (var i = 0; i < nbAddresses; i++) {
    geocoder.geocode({
        'address': address[i]
    }, return function(x) {  // we define a function and call it straight away. The function returns another function which is our callback.
        function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                mark = new google.maps.Marker({
                    position: results[0].geometry.location,
                    map: map,
                    title: titles[x]
                });
                map.setCenter(results[0].geometry.location);
                setInfoWindow();
             }
         }
    }(i)); // (i) after the function declaration calls the function and passes in the current value of i
}

基本的にここで行ったことは、関数を定義し、渡された 'i' の現在の値を使用してすぐに実行することでした。その後、関数は別の関数を返します。goecoding が終了すると、この関数が実行されます。しかし、関数が定義されたときと同じように、'i' への参照があります。したがって、x は、ジオコーダに渡されたアドレスに対応する i と等しくなるため、この関数の外部で x の記録を保持する必要がなくなりました。

これを閉鎖と呼びます。 JavaScript クロージャーはどのように機能しますか?

于 2013-01-03T16:25:51.717 に答える
0


x++ の変更;
setInfoWindow(); に

setInfoWindow();
x++;   
sets the problem !
于 2013-01-03T14:19:55.000 に答える