Search code examples
jquerygoogle-mapsgoogle-maps-api-3responsive-designenquire.js

Google map not showing when in a hidden div


I know this is a common issue reported on this site and elsewhere e.g.

But I can't get my issue solved.

So I've got a responsive site built Mobile first and I'm trying to get an adaptive map solution working i.e. mobile viewports get a static Google map image and for non-mobile viewports the full Google map API and this all has to update itself when the viewport resizes not just on page load. Based on this: http://codepen.io/bradfrost/pen/tLxAs.

I'm using this library.

I'm conditionally loading the Maps API only when it's needed (non-mobile viewports) via jQuery's $.getScript and the libraries setup() and defer() functions.

So that there's only the right map rendering at each viewport I'm using jQuery hide() and show() because of this the API map won't fully load itself (just 1 tile), well it does load fine if the page loads at a non-mobile viewport size, it's when you resize to mobile viewport back to non-mobile viewport size as that's when the show() method kicks in. Everything else works fine.

Here's my code:

HTML

<div class="map">
    <div class="map__static">
        <img src="http://maps.google.com/maps/api/staticmap?center=-33.867487,151.20699&zoom=15&markers=-33.867487,151.20699&size=650x405&sensor=false">
    </div>
</div>

The static map image is loaded by default as the site is built Mobile first.

JS

var mapContainer = $('.map'),
mapStaticContainer = $('.map__static');
mapDynamicContainer = $('<div class="map__dynamic"/>');

// Start Enquire library
enquire.register('screen and (min-width: 40em)', {

    deferSetup: true,

    setup: function setup() {
        mapContainer.prepend(mapDynamicContainer);
        mapDynamicContainer.load('/includes/scripts/adaptive-google-map.php', function() {
            $.getScript('https://maps.googleapis.com/maps/api/js?key=AIzaSyAywjPmf5WvWh_cIn35NwtIk-gYuwu1I2Q&sensor=false&callback=initialize');
        });
    },

    // Not mobile size viewport
    match: function() {
        mapStaticContainer.hide();
        mapDynamicContainer.show();
    },

    // Mobile size viewport
    unmatch: function() { 
        mapStaticContainer.show();
        mapDynamicContainer.hide();
    }

}, true).listen();

This is the contents of '/includes/scripts/adaptive-google-map.php' which is AJAX'd in via jQuery load().

<div id="map_canvas"></div>
<script>
    function initialize() {
    var myLatlng = new google.maps.LatLng(-33.867487,151.20699);
    var myOptions = {
      zoom: 15,
      center: myLatlng,
      mapTypeId: google.maps.MapTypeId.ROADMAP,
      scrollwheel: false
    }
    map = new google.maps.Map(document.getElementById('map_canvas'), myOptions);
    var marker = new google.maps.Marker({
        position: myLatlng,
        map: map,
        animation: google.maps.Animation.DROP
    });
    var contentString = 
        '<div class="infowindow">'+
            '<div>'+
                    '<p class="flush"><strong>SALES OFFICE:</strong><br>1/16 M. 5<br>Sydney<br>NSW, 83110.</p>'
            '</div>'+
        '</div>'
    ;
    var infowindow = new google.maps.InfoWindow({
        content: contentString
    });
    google.maps.event.addListener(marker, 'click', function() {
        infowindow.open(map,marker);
    });
    // Center Google Maps (V3) on browser resize (http://stackoverflow.com/questions/8792676/center-google-maps-v3-on-browser-resize-responsive)
    var center;
    function calculateCenter() {
        center = map.getCenter();
    }
    google.maps.event.addDomListener(map, 'idle', function() {
        calculateCenter();
    });
    google.maps.event.addDomListener(window, 'resize', function() {
        map.setCenter(center);
    });
    }
</script>

This fixes the problem:

mapDynamicContainer.show(function () {
    setTimeout(function() {
    initialize(); 
}, 100);
 })

But throws a JS error: Uncaught ReferenceError: initialize is not defined. Another common fix suggested by ppl. is applying this: google.maps.event.trigger(map, 'resize'); but when I put that after: mapDynamicContainer.show(); in the match() function I get this JS error: Uncaught ReferenceError: google is not defined.

Not having much luck :(


Solution

  • OK, so basically the "resize" is still your answer.

    I just modified your match to this piece of code:

    match: function() {
        mapStaticContainer.hide();
        mapDynamicContainer.show();
        if( typeof(map) != 'undefined'){
            var center = map.getCenter();
            google.maps.event.trigger(map, "resize");
            map.setCenter(center);
        }
     },
    

    and it's working. don't know if you have any other stuff in your code. I used html, js, and content of adaptive-google-map.php you provide and it works without any problems.