0

データを JSON 形式でロードし、ポイントをマップに追加する Google マップ API を使用してマップを作成しようとしています。

以下は、servername.com/kmltest/mapsapi.html からアクセスできる html ページです。

<!DOCTYPE html>
<html>
  <head>
    <title>Google Maps javascript</title>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <style>
      html, body, #map-canvas {
        height: 100%;
        margin: 0px;
        padding: 0px
      }
    </style>
    <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
    <script>

function drawAllPoints()
    {pointsData.numLayers = pointsData.layers.length;
        for (var i = 0; i < pointsData.numLayers; i++)
            {var numPoints = pointsData.layers[i].points.length;
            pointsData.layers[i].visible = true;

            document.getElementById("layerSidebarInner").innerHTML = document.getElementById("layerSidebarInner").innerHTML + "<input type=\"checkbox\" id=\"" + pointsData.layers[i].name + "\" >" + pointsData.layers[i].name + "<br />";
            //Eventually, make the checkbox trigger showing and hiding
            //pointsData.layers[i].layerColor = ; //Change a point color variable for this layer?
            for (var j = 0; j < numPoints; j++)
                {// Create a Lat/Long object.
                window.pointsData.layers[i].points[j].position = new google.maps.LatLng(window.pointsData.layers[i].points[j].lat, window.pointsData.layers[i].points[j].long);
                // Set up each point
                window.pointsData.layers[i].points[j].marker = new google.maps.Marker({
                    position: window.pointsData.layers[i].points[j].position,
                    map: window.map,
                    title : window.pointsData.layers[i].points[j].username
                });
                // Set up each information window
                infoWindow = new google.maps.InfoWindow({
                    position: window.pointsData.layers[i].points[j].position,
                    map: window.map,
                    title: window.pointsData.layers[i].points[j].username,
                    content: 'Test '+i+", "+j
                });
                // Try to add a handler that shows the balloon. Why does it show "2 2" and not the array indexes?
                google.maps.event.addListener(pointsData.layers[i].points[j].marker, 'click', function() {alert(i+" "+j);});
                }
        }
    }


var map;
var marker;
var myLatlng;

function initialize() {

myLatlng = new google.maps.LatLng(44.759705, -117.823371);
var mapOptions = {
zoom: 17,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.HYBRID
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);


// This used to be it's own function. Fires off a HTTP request for the Json customer data
var pointsDataJsonhttp;
// code for IE7+, Firefox, Chrome, Opera, Safari, I really don't care about IE6 and 5
pointsDataJsonhttp=new XMLHttpRequest();
pointsDataJsonhttp.onreadystatechange=function()
{
if (pointsDataJsonhttp.readyState==4 && pointsDataJsonhttp.status==200)
    {
    window.pointsData = eval("(" + pointsDataJsonhttp.responseText + ")");
    drawAllPoints();
    }
}
pointsDataJsonhttp.open("GET","/kmltest/test.json",true);
pointsDataJsonhttp.send();

}

//I can't seem to make this work yet, but I'm not worrying about it right now
/*function toggleLayer(layernumber)
{
    if (pointsData.layers[layernumber].visible) {
        pointsData.layers[layernumber] = false;
        }
    else {pointsData.layers[layernumber].visible = true;}
    numPoints = pointsData.layers[layernumber].points.length
    for (j=0; j < numPoints; j++)
        {
        pointsData.layers[layernumber].points[j].setVisible(pointsData.layers[layernumber].visible);
        }
}*/

// Seems like these two do the same thing, so I'm only using one of them
google.maps.event.addDomListener(window, 'load', initialize);

//window.onload = initialize;

    </script>
  </head>
  <body>
    <div id="layerSidebar" style="width: 20%; float: left;"><div id="layerSidebarInner" style="margin:10px;"></div></div>
    <div id="map-canvas" style="width: 80%; float: left;"></div>
    <!-- This line makes any following content get below the bottom of the 2 columns above -->
    <div style="clear: both"></div>
  </body>
</html>

これは、servername.com/kmltest/test.json のサーバーで利用可能な、ロード中の (現在は静的な) JSON です。

{ "layers" :
    [
        {"name" : "Shelf18", 
        "broadband": "adsl",
        "type" : "customerlist",
        "points" :
            [ {"username" : "thompsondsl", "long" : -117.823711, "lat" : 44.760645, "shelf" : "18", "slot": "3", "port" : "2"},
            {"username": "johnsondsl", "long" : -117.822471, "lat" : 44.759705, "shelf": "18", "slot": "3", "port" : "3"}
            ]
        },
        {"name" : "Shelf17",
        "broadband": "adsl",
        "type" : "customerlist",
        "points" :
            [ {"username" : "andersendsl17", "long" : -117.823811, "lat" : 44.760645, "shelf" : "18", "slot": "4", "port" : "2"},
            {"username": "smithdsl", "long" : -117.823371, "lat" : 44.759705, "shelf": "18", "slot": "11", "port" : "3"}
            ]
        }
    ]
}

ご覧のとおり、デバッグを支援するために警告ボックスをいくつか入れました。目印をクリックすると、クリックした目印に応じて「0 1」のような結果ではなく、常に「2 2」の結果が得られる理由がわかりません。ループ制御変数が最終的に値を取得するかのようです。それが起こっている場合、それが起こらないように適切に行うにはどうすればよいですか?

4

1 に答える 1

1

コードを関数でラップしてみてください。これにより、 と のローカル コピーを含むプライベート コンテキストが作成されiますj

(function (i, j) {
    var marker = pointsData.layers[i].points[j].marker;
    google.maps.event.addListener(marker, 'click', function() { 
        alert(i + " " + j); 
    });
})(i, j);

次のようにすることもできます。

var marker = pointsData.layers[i].points[j].marker;
google.maps.event.addListener(marker, 'click', function() { 
    return function() { alert(i + " " + j); };
}(i, j));
于 2013-10-16T05:26:45.060 に答える