Mehrere Google Maps mit zentriertem Marker in Foundation Reveal Modals auf einer Seite

von

Neulich stand ich vor einem auf den ersten Blick verzwickten Problem. Es sollten auf einer Seite Google Maps gezeigt werden. Mehrere. Diese sollten zudem in Modal Fenstern eingebunden sein. Da die Seite mit Foundation gebaut ist, musste ich also Reveal Modal Fenster benutzen.

Nun stellte sich aber beim ersten Versuch, die Google Maps mittels iFrame einzubinden, heraus, daß der Marker immer völlig falsch am linken oberen Rand der Kartenfläche positioniert war, da die Karte im iFrame onload generiert wurde und zu diesem Zeitpunkt das Reveal Modal ja noch Quark im Schaufenster ist.

Also schaute ich mir zuerst die Google Maps API v3 an. Eine super Sache, vielseitig und kaum von der Bettkante zu schubsen. Dann war der letzte Schritt nur noch, die Google Karten im Callback der Reveal Modals zu initialisieren, so daß der Marker immer im Zentrum steht. Voila, JS Bin Demo und Code:

<!DOCTYPE html>
<html>
<head>
<link href="http://cdnjs.cloudflare.com/ajax/libs/foundation/5.0.3/css/normalize.min.css" rel="stylesheet" type="text/css" />
<link href="http://cdnjs.cloudflare.com/ajax/libs/foundation/5.0.3/css/foundation.min.css" rel="stylesheet" type="text/css" />
<script src="http://cdnjs.cloudflare.com/ajax/libs/foundation/5.0.3/js/vendor/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/foundation/5.0.3/js/foundation.min.js"></script>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=AIzaSyDEbRv070GUYNDHSrK8FzNPakJKl3wBmeg&amp;sensor=TRUE"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  
  <div class="row">
    <div class="large-12 columns">
    <ul class="pagination">
      <li><a href="#" class="reveal-map" data-loc="1">Show Location 1</a></li>
      <li><a href="#" class="reveal-map" data-loc="2">Show Location 2</a></li>
    </ul>
    </div>
  </div>
  
  <div class="reveal-modal row" data-loc="1" data-reveal>
    <div class="large-12 columns mapcontainer">
      <div id="map_canvas_1" style="width:100%; height:300px;"></div>
    </div>
    <a href="#" class="close-reveal-modal">&times;</a>
  </div>
  
   <div class="reveal-modal row" data-loc="2" data-reveal>
    <div class="large-12 columns mapcontainer">
      <div id="map_canvas_2" style="width:100%; height:300px;"></div>
    </div>
    <a href="#" class="close-reveal-modal">&times;</a>
  </div>
  
</body>
</html>
.infowindow {
  width: 120px;
  height: 40px;
  text-align: center;
}
//  setup vars for every map
var locations = { 
  "loc" : [{ 
      "center" : {
      "x" : 52.56915,
      "y" : 13.41108
      },
      "content" : '<div class="infowindow">Location1<br/><a target="_blank" href="https://www.google.com/maps/place/Paschotka+Orthop%C3%A4dieschuhtechnik/@52.569147,13.411167,17z/data=!3m1!4b1!4m2!3m1!1s0x47a8526c2c99d08b:0x939e54a0dbd87541?hl=de-DE">Route planen</a></div>',
      "title" : "Location 1"
    },
    { 
      "center" : {
      "x" : 52.564736,
      "y" : 13.328535
      },
      "content" : '<div class="infowindow">Location2<br/><a target="_blank" href="https://www.google.com/maps/place/Paschotka+Orthop%C3%A4dieschuhtechnik/@52.569147,13.411167,17z/data=!3m1!4b1!4m2!3m1!1s0x47a8526c2c99d08b:0x939e54a0dbd87541?hl=de-DE">Route planen</a></div>',
      "title" : "Location 2"
    }]
};
 
// initialise google map with current location, takes current location and locations obj
// reference: https://developers.google.com/maps/documentation/javascript/reference?hl=de
function initialize( current, locations ) {
  
  var mapLatLng = new google.maps.LatLng(
    locations.loc[current].center.x,
    locations.loc[current].center.y
  );
  
  var mapOptions = {
    center: mapLatLng,
    zoom: 15,
    disableDefaultUI: true,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  
  var map = new google.maps.Map( document.getElementById( "map_canvas_" + ( current + 1 ) ), mapOptions );
  
  var marker = new google.maps.Marker({
    position: mapLatLng,
    map: map,
    title: locations.loc[current].title
  });
  
  var infowindow = new google.maps.InfoWindow({ content: locations.loc[current].content });
  
  // open infowindow on init
  infowindow.open(map, marker);
  
  // open infowindow by clicking on marker
  google.maps.event.addListener(marker, 'click', function() {
    infowindow.open(map, marker);
  });
  
}
 
// init foundation js
$(document).foundation();
 
// bind google map init to "opened" event of foundation reveal
// reference: http://foundation.zurb.com/docs/components/reveal.html
$(document).on('opened.fndtn.reveal', '[data-reveal]', function () {
  initialize( parseInt( $(this).attr('data-loc') ) - 1, locations );
});
 
// bind open action to links with specified attr data.loc
$('a.reveal-map').on( "click", function() {
  $('.reveal-modal[data-loc="' + $(this).attr('data-loc') + '"]' ).foundation('reveal', 'open');
});

Kommentieren