Google Maps Display:None Problem

I'm trying to set up a Google map that will display when a link is clicked and then hide when another link is clicked. Everything works fine, except when I show the map from display:none, it doesn't display properly.

I read about using google.maps.event.trigger(map, 'resize'); but I'm not proficient enough with Javascript and JQuery to know how to add it in.

Here's the code I've been using:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 TRANSITIONAL//EN">
<html>
    <head>
        <title></title>
        <style type="text/css">
            #viewmap {
                position:relative;
                width:944px;
                float:left;
                display:none;
            }
            #hidemap {
                position:relative;
                width:944px;
                float:left;
                display:block;
            }
            #map_canvas {
                position:relative;
                float:left;
                width:944px;
                height:300px;
            }
        </style>
        <script type="text/javascript"
            src="http://maps.google.com/maps/api/js?v=3.2&sensor=false">
        </script>
        <script type="text/javascript">
            function initialize() {
                var latlng = new google.maps.LatLng(-27.999673,153.42855);
                var myOptions = {
                    zoom: 15,
                    center: latlng,
                    mapTypeId: google.maps.MapTypeId.ROADMAP,
                    mapTypeControl: true,
                    mapTypeControlOptions: {
                        style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
                    }
                };

                var map = new google.maps.Map(document.getElementById("map_canvas"),myOptions);

                var contentString = 'blah';

                var infowindow = new google.maps.InfoWindow({
                    content: contentString
                });

                var marker = new google.maps.Marker({
                    position: latlng, 
                    map: map
                });

                google.maps.event.addListener(marker, 'click', function() {
                    infowindow.open(map,marker);
                });
            }

            google.maps.event.addDomListener(window, 'load', initialize);
        </script>
        <script type="text/javascript">
            function toggleDiv1(viewmap){
                if(document.getElementById(viewmap).style.display == 'block'){
                    document.getElementById(viewmap).style.display = 'none';
                }else{
                    document.getElementById(viewmap).style.display = 'block';
                }
            }
            function toggleDiv2(hidemap){
                if(document.getElementById(hidemap).style.display == 'none'){
                    document.getElementById(hidemap).style.display = 'block';
                }else{
                    document.getElementById(hidemap).style.display = 'none';
                }
            }
        </script>
    </head>
    <body>
        <div id="viewmap">
            <a href="#" onmousedown="toggleDiv1('viewmap'); toggleDiv2('hidemap');">Hide map</a>
            <div id="map_canvas"></div>
        </div>
        <div id="hidemap">
            <a href="#" onmousedown="toggleDiv1('viewmap'); toggleDiv2('hidemap');">View map</a>
        </div>
    </body>
</html>

Any help would be much appreciated,

Quintin

Answers:

Answer

This problems also happens with the jquery tabs, instead of applying "display:none", you can try hidding the map in this way:

Add the following styles when you are trying to hide the map, instead of using display:none

position: absolute;
left: -100%;

You can also add transitions like: transition: left 1s ease;

You can try with google event listener triggering it after you display the map:

<script type="text/javascript">
    var map; //I placed here the map variable so other functions can see it.
    var latlng = new google.maps.LatLng(-27.999673,153.42855); 
    // in order to center again the map...
    function initialize() {

        var myOptions = {
            zoom: 15,
            center: latlng,
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            mapTypeControl: true,
            mapTypeControlOptions: {
                style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
            }
        };

        map = new google.maps.Map(document.getElementById("map_canvas"),myOptions);

        var contentString = 'blah';

        var infowindow = new google.maps.InfoWindow({
            content: contentString
        });

        var marker = new google.maps.Marker({
            position: latlng, 
            map: map
        });

        google.maps.event.addListener(marker, 'click', function() {
            infowindow.open(map,marker);
        });
    }

    google.maps.event.addDomListener(window, 'load', initialize);
</script>
<script type="text/javascript">
    function toggleDiv1(viewmap){
        if(document.getElementById(viewmap).style.display == 'block'){
            document.getElementById(viewmap).style.display = 'none';
        }else{
            document.getElementById(viewmap).style.display = 'block';
            //here is where your map is being displayed again, try here
            // to trigger the resize event.
            google.maps.event.trigger(map, 'resize');
            map.setCenter(latlng);
        }
    }
    function toggleDiv2(hidemap){
        if(document.getElementById(hidemap).style.display == 'none'){
            document.getElementById(hidemap).style.display = 'block';
        }else{
            document.getElementById(hidemap).style.display = 'none';
        }
    }
</script>
Answer

I ran into this same problem today and eventually found this at the official Google Maps Javascript API V3 Reference:

Developers should trigger this event on the map when the div changes size: google.maps.event.trigger(map, 'resize') .

As display:none is equivalent to leaving the <div> with size 0, changing it to display:block becomes in fact a change of size, making therefore necessary to trigger the map resize event.

Worked like a charm for me.

UPDATE 2018-05-22

With a new renderer release in version 3.32 of Maps JavaScript API the resize event is no longer a part of Map class.

The documentation states

When the map is resized, the map center is fixed

  • The full-screen control now preserves center.

  • There is no longer any need to trigger the resize event manually.

source: https://developers.google.com/maps/documentation/javascript/new-renderer

google.maps.event.trigger(map, "resize"); doesn't have any effect starting from version 3.32

Answer

The problem with size of the map is that it needs to know the size of the div that it is rendering to. At the moment you are initializing a map on document load when your div is hidden so the map cannot calculate its size correctly - to solve this problem you simply need to initialize it first time you show the div (not onload).

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 TRANSITIONAL//EN">
<html>
    <head>
        <title></title>
        <style type="text/css">
            #viewmap {
                position:relative;
                width:944px;
                float:left;
                display:none;
            }
            #hidemap {
                position:relative;
                width:944px;
                float:left;
                display:block;
            }
            #map_canvas {
                position:relative;
                float:left;
                width:944px;
                height:300px;
            }
        </style>
        <script type="text/javascript"
            src="http://maps.google.com/maps/api/js?v=3.2&sensor=false">
        </script>
        <script type="text/javascript">
        //your global map object
        var map = null;
            function initialize() {
                var latlng = new google.maps.LatLng(-27.999673,153.42855);
                var myOptions = {
                    zoom: 15,
                    center: latlng,
                    mapTypeId: google.maps.MapTypeId.ROADMAP,
                    mapTypeControl: true,
                    mapTypeControlOptions: {
                        style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
                    }
                };

                map = new google.maps.Map(document.getElementById("map_canvas"),myOptions);

                var contentString = 'blah';

                var infowindow = new google.maps.InfoWindow({
                    content: contentString
                });

                var marker = new google.maps.Marker({
                    position: latlng, 
                    map: map
                });

                google.maps.event.addListener(marker, 'click', function() {
                    infowindow.open(map,marker);
                });

            }


            function toggleDiv1(viewmap){
                if(document.getElementById(viewmap).style.display == 'block'){
                    document.getElementById(viewmap).style.display = 'none';
                }else{
                    document.getElementById(viewmap).style.display = 'block';
                    //check if map object exists (it is created by you initialize function), if not initialize it
                    if (!map) {
                    initialize();

                    }
                }
            }
            function toggleDiv2(hidemap){
                if(document.getElementById(hidemap).style.display == 'none'){
                    document.getElementById(hidemap).style.display = 'block';
                }else{
                    document.getElementById(hidemap).style.display = 'none';
                }
            }
        </script>
    </head>
    <body>
        <div id="viewmap">
            <a href="#" onmousedown="toggleDiv1('viewmap'); toggleDiv2('hidemap');">Hide map</a>
            <div id="map_canvas"></div>
        </div>
        <div id="hidemap">
            <a href="#" onmousedown="toggleDiv1('viewmap'); toggleDiv2('hidemap');">View map</a>
        </div>
    </body>
</html>
Answer

Just initialize the map when you want to display it. I had the same problem and solved it this way.

Remove this line:

google.maps.event.addDomListener(window, 'load', initialize);

And change the toggleDiv script this way:

function toggleDiv1(viewmap){  
  if(document.getElementById(viewmap).style.display == 'block'){  
      document.getElementById(viewmap).style.display = 'none';  
   }else{  
      document.getElementById(viewmap).style.display = 'block';  
      initialize();  
   }  
}  
function toggleDiv2(hidemap){  
   if(document.getElementById(hidemap).style.display == 'none'){  
       document.getElementById(hidemap).style.display = 'block';  
   }else{  
       document.getElementById(hidemap).style.display = 'none';  
   }  
}  
Answer

.map_container {display:none;}

$('.show_hide').click(function(){
    $('.map_container').toggle({
        complete:function (){
            google.maps.event.trigger(map, 'resize');
        },
        duration:'slow'
    });
})
Answer

You indeed better using the off-left technique!
Here is my edits:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 TRANSITIONAL//EN">
<html>
    <head>
        <title></title>
        <style type="text/css">
            #viewmap {
                position:relative;
                width:944px;
                float:left;
            }
            #hidemap {
                position:relative;
                width:944px;
                float:left;
            }
            #map_canvas {
                position:relative;
                float:left;
                width:944px;
                height:300px;
            }
          .good-bye {
            position: absolute !important;
            left: -10000px !important;
          }
        </style>
        <script type="text/javascript"
            src="http://maps.google.com/maps/api/js?v=3.2&sensor=false">
        </script>
        <script type="text/javascript">
            function initialize() {
                var latlng = new google.maps.LatLng(-27.999673,153.42855);
                var myOptions = {
                    zoom: 15,
                    center: latlng,
                    mapTypeId: google.maps.MapTypeId.ROADMAP,
                    mapTypeControl: true,
                    mapTypeControlOptions: {
                        style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
                    }
                };

                var map = new google.maps.Map(document.getElementById("map_canvas"),myOptions);

                var contentString = 'blah';

                var infowindow = new google.maps.InfoWindow({
                    content: contentString
                });

                var marker = new google.maps.Marker({
                    position: latlng,
                    map: map
                });

                google.maps.event.addListener(marker, 'click', function() {
                    infowindow.open(map,marker);
                });
            }

            google.maps.event.addDomListener(window, 'load', initialize);
        </script>
        <script type="text/javascript">
            function toggleDiv1(viewmap){
              if(hasClass(document.getElementById(viewmap), 'good-bye'))
                removeClass(document.getElementById(viewmap), 'good-bye');
              else
                addClass(document.getElementById(viewmap), 'good-bye');
              return;
            }
            function toggleDiv2(hidemap){
              if(hasClass(document.getElementById(hidemap), 'good-bye'))
                removeClass(document.getElementById(hidemap), 'good-bye');
              else
                addClass(document.getElementById(hidemap), 'good-bye');
              return;
            }

            // http://snipplr.com/view/3561/addclass-removeclass-hasclass/
            function hasClass(ele,cls) {
              return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
            }

            function addClass(ele,cls) {
              if (!this.hasClass(ele,cls)) ele.className += " "+cls;
            }

            function removeClass(ele,cls) {
              if (hasClass(ele,cls)) {
                var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
                ele.className=ele.className.replace(reg,' ');
              }
            }
        </script>
    </head>
    <body>
        <div id="viewmap" class="good-bye">
            <a href="#" onmousedown="toggleDiv1('viewmap'); toggleDiv2('hidemap'); return false;">Hide map</a>
            <div id="map_canvas"></div>
        </div>
        <div id="hidemap">
            <a href="#" onmousedown="toggleDiv1('viewmap'); toggleDiv2('hidemap');">View map</a>
        </div>
    </body>
</html>

Example Link.

Answer

Pretty simple... by the time you initialize the map all of its outer divs have to already be displayed.

So just initialize the map at the very end:

setTimeout(function(){
    $mapsOuterDiv.slideToggle(700);
    setTimeout(function(){
        initializeGoogleMap();
    },300);
},300);
Answer

Also i have found another solution. Sometimes you need to call refresh() on google maps object and map will be forced to resize.

// gmaps - instance of particular map ...
gmaps.refresh()
Answer

This code work right (using jQuery 1.2.6): Css: #gog-map{position:absolute; visibility:hidden;}

$(document).ready(function() {
  $('a#link').click(function() {
    if ($('#gog-map').is(':visible')){
      $('#gog-map').slideUp('slow');            
    } else{
      $('#gog-map').slideDown('slow');
      $("#gog-map").css('visibility','inherit');
      $("#gog-map").css('position','relative');
    }
     return false;
  });
});

Answer

I've been trying to animate my maps with no luck and finally came up with this:

CSS: We set the map wrapper with position:absolute; and visibility:hidden; because it has to have its normal dimensions to properly render.

JavaScript:

$(document).ready(function() 
{
    // We then run this function only once per page load. It places out map back in the document flow but hides it before it starts to toggle its height.
    $("#mapBtn").one("click", function() 
    {
        $("#myMap").hide(); 
        $("#myMap").css("visibility", "inherit");
        $("#myMap").css("position", "relative");
    });

    // And now we toggle away nicely
    $("#mapBtn").click(function() 
    {
        $("#myMap").slideToggle(400);
    });
});
Answer

Generally google.maps.event.trigger(map, 'resize') will refresh the map and thus append the code after whenever it is displayed, since the previous state of display is "none":

    document.getElementById(hidemap).style.display = 'block'; 
    Generally google.maps.event.trigger(map, 'resize')
Answer

There is an example in the documentation: https://developers.google.com/maps/documentation/javascript/examples/control-replacement

And if you don't want the control to be located in the map area, just comment out the following line:

map.controls[google.maps.ControlPosition.RIGHT_TOP].push(fullscreenControl);
Answer
document.getElementById('map_canvas').style.display = 'none'; 

This worked fine for me - don't know if that's because I'm hiding the canvas rather than the containing div....works fine in IE, Firefox and Chrome. Sure you can hide your container once the map canvas is hidden.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.