Google MAPS APIで遊んでいて、複数のgoogle.maps.Marker (GMarker) の、それぞれに吹き出し(openInfoWindow)をつけたかったのに、どれをクリックしても最後のマーカーから吹き出しが出てくる!というミスをしないための備忘録。質問しても「クロージャがわかってない奴は云々」とか説教垂れられるだけなので。
API keyが不要なV3版はこちらです。
↓ここで使っているコード。
google.load("maps", "2", {"language" : "ja_JP"}); function myMarker(lat, lng, msg) { var marker = new google.maps.Marker(new google.maps.LatLng(lat, lng)); google.maps.Event.addListener(marker, "click", function() { marker.openInfoWindowHtml(msg); }); return marker; } function init() { var map = new google.maps.Map2(document.getElementById("map")); map.setCenter(new google.maps.LatLng(34.842, 135.53), 13); map.addOverlay(myMarker(34.806750, 135.530150, "万博記念公園")); map.addOverlay(myMarker(34.810889, 135.539656, "公園東口")); map.addOverlay(myMarker(34.818611, 135.529747, "阪大病院前")); map.addOverlay(myMarker(34.834611, 135.526778, "豊川")); map.addOverlay(myMarker(34.855492, 135.522931, "彩都西")); } google.setOnLoadCallback(init);
~ よくある悲劇 ~
↓このように、forループ内で addListener() を呼んじゃぁ、ダ~メダ~メ!
なぜならば、clickイベントが呼ばれた時、既にforループはオワっていて、i = 5なので pos[i] is undefined
// ダメコード function init() { var map = new google.maps.Map2(document.getElementById("map")); map.setCenter(new google.maps.LatLng(34.842, 135.53), 13); var pos = new Array(); pos.push(new Array(34.806750, 135.530150, "万博記念公園")); pos.push(new Array(34.810889, 135.539656, "公園東口")); pos.push(new Array(34.818611, 135.529747, "阪大病院前")); pos.push(new Array(34.834611, 135.526778, "豊川")); pos.push(new Array(34.855492, 135.522931, "彩都西")); for (i = 0; i < pos.length; pos++) { var marker = new google.maps.Marker(new google.maps.LatLng(pos[i][0], pos[i][1])); google.maps.Event.addListener(marker, "click", function() { marker.openInfoWindowHtml(pos[i][2]); }); map.addOverlay(marker); } }
↓せめてこんな感じに。
function myMarker(p) { var marker = new google.maps.Marker(new google.maps.LatLng(p[0], p[1])); google.maps.Event.addListener(marker, "click", function() { marker.openInfoWindowHtml(p[2]); }); return marker; } function init() { map = new google.maps.Map2(document.getElementById("map")); map.setCenter(new google.maps.LatLng(34.842, 135.53), 13); var pos = new Array(); pos.push(new Array(34.806750, 135.530150, "万博記念公園")); pos.push(new Array(34.810889, 135.539656, "公園東口")); pos.push(new Array(34.818611, 135.529747, "阪大病院前")); pos.push(new Array(34.834611, 135.526778, "豊川")); pos.push(new Array(34.855492, 135.522931, "彩都西")); for (i = 0; i < pos.length; pos++) { var marker = myMarker(pos[i]); map.addOverlay(marker); } }
↓Array.push()が不安?
function myMarker(p) { var marker = new google.maps.Marker(new google.maps.LatLng(p[0], p[1])); google.maps.Event.addListener(marker, "click", function() { marker.openInfoWindowHtml(p[2]); }); return marker; } function init() { map = new google.maps.Map2(document.getElementById("map")); map.setCenter(new google.maps.LatLng(34.842, 135.53), 13); var pos = new Array(); pos[pos.length] = new Array(34.806750, 135.530150, "万博記念公園"); pos[pos.length] = new Array(34.810889, 135.539656, "公園東口"); pos[pos.length] = new Array(34.818611, 135.529747, "阪大病院前"); pos[pos.length] = new Array(34.834611, 135.526778, "豊川"); pos[pos.length] = new Array(34.855492, 135.522931, "彩都西"); for (i = 0; i < pos.length; pos++) { var marker = myMarker(pos[i]); map.addOverlay(marker); } }