複数のgoogle.maps.Markerに吹き出しをつける

Google MAPS APIで遊んでいて、複数のgoogle.maps.Marker の、それぞれに吹き出し(openInfoWindow)をつけたかったのに、どれをクリックしても最後のマーカーから吹き出しが出てくる!というミスをしないための備忘録。質問しても「クロージャがわかってない奴は云々」とか説教垂れられるだけなので。。

V2 版はこちらです。


<script type="text/javascript" src="//maps.google.com/maps/api/js?sensor=false"></script>

<div id="map" style="width: 740px; height: 400px;"></div>
<script type="text/javascript">
  function attachMessage(marker, msg) {
    google.maps.event.addListener(marker, 'click', function(event) {
      new google.maps.InfoWindow({
        content: msg
      }).open(marker.getMap(), marker);
    });
  }
// 位置情報と表示データの組み合わせ
  var data = new Array();
  data.push({position: new google.maps.LatLng(35.697745, 139.826395), content: '亀戸'});
  data.push({position: new google.maps.LatLng(35.700295, 139.833692), content: '亀戸水神'});
  data.push({position: new google.maps.LatLng(35.707055, 139.831897), content: '東あずま'});
  data.push({position: new google.maps.LatLng(35.710127, 139.828033), content: '小村井'});
  data.push({position: new google.maps.LatLng(35.717753, 139.816786), content: '曳舟'});

  var myMap = new google.maps.Map(document.getElementById('map'), {
    zoom: 14,
    center: new google.maps.LatLng(35.71, 139.83),
    scrollwheel: false,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  });

  for (i = 0; i < data.length; i++) {
    var myMarker = new google.maps.Marker({
      position: data[i].position,
      map: myMap
    });
    attachMessage(myMarker, data[i].content);
  }
</script>

こちらは動かないコード data[i] is undefinedになります。
何故ならclickイベントが呼ばれた時、i = 5なので。

// ダメコード
<script type="text/javascript">

  var data = new Array();
  data.push({position: new google.maps.LatLng(35.697745, 139.826395), content: '亀戸'});
  data.push({position: new google.maps.LatLng(35.700295, 139.833692), content: '亀戸水神'});
  data.push({position: new google.maps.LatLng(35.707055, 139.831897), content: '東あずま'});
  data.push({position: new google.maps.LatLng(35.710127, 139.828033), content: '小村井'});
  data.push({position: new google.maps.LatLng(35.717753, 139.816786), content: '曳舟'});

  var myMap = new google.maps.Map(document.getElementById('map'), {
    zoom: 12,
    center: new google.maps.LatLng(35.71, 139.83),
    mapTypeId: google.maps.MapTypeId.ROADMAP
  });

  for (i = 0; i < data.length; i++) {
    var myMarker = new google.maps.Marker({
      position: data[i].position,
      map: myMap
    });
    google.maps.event.addListener(myMarker, 'click', function(event) {
      new google.maps.InfoWindow({
        content: data[i].content // どのマーカーがクリックされても、その時点では i = 5
      }).open(myMap, myMarker);
    });
  }
</script>

次は動的に内容を取得して表示するサンプル。
逆ジオコーディングして、それぞれの位置の住所を取得して吹き出しに表示させます。


<script type="text/javascript">
  function attachMessage(marker) {
    google.maps.event.addListener(marker, 'click', function() {
      new google.maps.Geocoder().geocode({
        latLng: marker.getPosition()
      }, function(result, status) {
        if (status == google.maps.GeocoderStatus.OK) {
          new google.maps.InfoWindow({
            content: result[0].formatted_address
          }).open(marker.getMap(), marker);
        }
      });
    });
  }

  var data = new Array();
  data.push(new google.maps.LatLng(35.697745, 139.826395));
  data.push(new google.maps.LatLng(35.700295, 139.833692));
  data.push(new google.maps.LatLng(35.707055, 139.831897));
  data.push(new google.maps.LatLng(35.710127, 139.828033));
  data.push(new google.maps.LatLng(35.717753, 139.816786));

  var myMap = new google.maps.Map(document.getElementById('map'), {
    zoom: 14,
    center: new google.maps.LatLng(35.71, 139.83),
    scrollwheel: false,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  });
  for (i = 0; i < data.length; i++) {
    var myMarker = new google.maps.Marker({
      position: data[i],
      map: myMap
    });
    attachMessage(myMarker);
  }
</script>