2008年10月20日
思ったとおりに動いてくれない
forループ内で読んだGEvent.addListenerが意図した動作をしてくれない。
症状とコードは下記の通り。
- マーカーは作られる
- しかし、どのマーカーをクリックしても同一マーカーから情報窓が出てくる
for (var i = 0; i< loaddata.data.length; i++) {
var point = new GLatLng(data[i].lat, data[i].lng);
var marker = new GMarker(point);
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml("Marker #" + i);
});
map.addOverlay(marker);
}
※dataは連想配列の配列とする
解決策はクロージャにあり
検索してみたけど、同じ現象を解決したエントリを見つけられなかった。
APIのドキュメントを読んでいたら解決策を見つけた。
イベント リスナでクロージャを使用する
イベント リスナを実行するときは、オブジェクトにプライベート データと永続データの両方を添付することが一般に有効です。JavaScript は「プライベート」インスタンスデータをサポートしていませんが、内部関数が外部変数にアクセスすることを可能にするクロージャ をサポートしています。イベントリスナ内でクロージャを使用すると、イベントが発生したオブジェクトには通常添付されていない変数にアクセスできるので便利です。
次の例では、イベント リスナ内で関数クロージャを使用して、一連のマーカーにシーケンス番号値を割り当てています。各マーカーをクリックすると、そのマーカー自体には含まれていない個別の値が表示されます。
なるほど…
function createMarker(point, number) {
var marker = new GMarker(point);
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml("Marker #" + number);
});
return marker;
}
for(var i = 0; i< loaddata.data.length; i++) {
var point = new GLatLng(data[i].lat, data[i].lng);
map.addOverlay(createMarker(point, i));
}
これで無事に解決した
Google Maps Hacks 第2版 ―地図検索サービスをもっと活用するテクニック
posted with amazlet at 08.10.20
Rich Gibson Schuyler Erle
オライリー・ジャパン
売り上げランキング: 49910
オライリー・ジャパン
売り上げランキング: 49910
トラックバックURL
この記事へのコメント
1. Posted by しげる 2009年05月15日 17:41
参考になりました。ありがとうございます。
僕の場合はデータベースとマーカーマネージャの使用を考えてこんな感じになりました。
(markerIconはGIconのインスタンス)
function createMarker(point, record) {
var marker = new GMarker(point, {icon:markerIcon});
GEvent.addListener(marker, "click", function(){
marker.openInfoWindowHtml(record.title+"<br/>"+record.date);
});
return marker;
}
for (var i in db) {
var record = db[i];
var point = new GLatLng(record.lat, record.lng);
manager.addMarker(createMarker(point, record), record.minZoom);
}
僕の場合はデータベースとマーカーマネージャの使用を考えてこんな感じになりました。
(markerIconはGIconのインスタンス)
function createMarker(point, record) {
var marker = new GMarker(point, {icon:markerIcon});
GEvent.addListener(marker, "click", function(){
marker.openInfoWindowHtml(record.title+"<br/>"+record.date);
});
return marker;
}
for (var i in db) {
var record = db[i];
var point = new GLatLng(record.lat, record.lng);
manager.addMarker(createMarker(point, record), record.minZoom);
}
