comment gérer la carte google à l'intérieur d'un div caché (image mise à jour)

127

J'ai une page et une carte google est dans un div caché au début. J'affiche ensuite le div après avoir cliqué sur un lien, mais seul le coin supérieur gauche de la carte apparaît.

j'ai essayé de faire exécuter ce code après le clic:

    map0.onResize();

ou:

  google.maps.event.trigger(map0, 'resize')

des idées. voici une image de ce que je vois après avoir montré le div avec la carte cachée.texte alternatif

Léora
la source
Il y a déjà un certain nombre de questions sur SO à ce sujet, y compris l' affichage de la carte Google à partir d'une zone cachée
Matt Ball
@Matt Ball - comme mis à jour, j'ai essayé d'ajouter l'événement de redimensionnement mais ne fonctionne toujours pas
leora
@Matt Ball - j'ai réussi à faire fonctionner ça. après avoir créé l'objet google map, je le stocke dans une variable globale afin de pouvoir le référencer à nouveau plus tard et l'appel de redimensionner semble maintenant fonctionner. J'essaie de ne pas avoir à recréer l'objet de la carte à chaque fois que je le montre parce que j'autorise les gens à basculer.
leora
@ooo c'est très simple avec le code ci-dessous. Tout ce que vous devez ajouter est une condition if pour vérifier si l'objet de la carte a été initialisé ou non. Il s'agissait d'un code prêt à l'emploi écrit pour résoudre votre problème initial qui est de charger correctement la carte.
Philar
@philar - ouais. . merci ici. . ainsi le vote positif :). Quoi qu'il en soit, je dois stocker les variables au niveau global pour éviter la réinitialisation
leora

Réponses:

103

Je viens de le tester moi-même et voici comment je l'ai abordé. Assez simple, faites-moi savoir si vous avez besoin de clarification

HTML

<div id="map_canvas" style="width:700px; height:500px; margin-left:80px;" ></div>
<button onclick="displayMap()">Show Map</button>

CSS

<style type="text/css">
#map_canvas {display:none;}
</style>

Javascript

<script>
function displayMap()
{
    document.getElementById( 'map_canvas' ).style.display = "block";
    initialize();
}
function initialize()
{
    // create the map
    var myOptions = {
        zoom: 14,
        center: new google.maps.LatLng( 0.0, 0.0 ),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    }
    map = new google.maps.Map( document.getElementById( "map_canvas" ),myOptions );
}
</script>
Philar
la source
Donc, fondamentalement, vous instancialisez la carte uniquement lorsque le div est affiché? Existe-t-il un moyen de le faire pour que l'objet de la carte ne soit instancié qu'une seule fois (lors du chargement de la page)?
lucas
1
Je pourrais également suggérer un délai setTimeout pour appeler la deuxième fonction si vous appelez un show () pour laisser le temps de redimensionner.
Eric 18
126

J'avais le même problème et j'ai découvert que lorsque vous montrez le div, appelez google.maps.event.trigger(map, 'resize');et cela semble résoudre le problème pour moi.

Eric
la source
64
Afin de conserver le centre d'origine de la carte juste après le redimensionnement, envisagez d'étendre l'instruction de redimensionnement de cette façon: var center = map.getCenter (); google.maps.event.trigger (carte, 'redimensionner'); map.setCenter (centre);
John Doppelmann
10
Je ne sais pas pourquoi, mais je dois envelopper la solution dans un petit setTimeout pour qu'elle fonctionne: setTimeout (function () {google.maps.event.trigger (map, 'resize')}, 100);
HoffZ
@JohnDoppelmann Merci pour le tuyau! Ce n'était pas intuitif pourquoi il ne maintenait pas le centre, ni comment le forcer à revenir.
Noah Duncan
Réglez à nouveau le centre de la carte et le niveau de zoom après avoir déclenché l'événement «redimensionner». Pour plus d'informations, voir: code.google.com/p/gmaps-api-issues/issues/detail?id=1448
ruhong
@HoffZ cela est probablement dû au déclenchement de votre code de redimensionnement avant l'effet d'affichage, le délai d'attente le retarde jusqu'à ce que le spectacle soit effectué, puis le redimensionnement peut le faire fonctionner. Vous pouvez probablement obtenir le même effet en modifiant l'ordre d'exécution de votre code pour vous assurer que lors du déclenchement de l'événement, l'affichage div est exécuté avant le redimensionnement de la carte.
Bardo
26
google.maps.event.trigger($("#div_ID")[0], 'resize');

Si vous n'avez pas de divtable de variables disponible, ce devrait être le premier élément (à moins que vous n'ayez fait quelque chose de stupide) dans le contenant GMAP.

CSN
la source
Êtes-vous sûr de pouvoir déclencher un élément sur un div au lieu d'un objet google.map.Map ?
Salman A
@SalmanA - Je viens de vérifier cela et cela a fonctionné pour moi (bien que la carte semble avoir un nouveau centre). D'après des recherches précédentes, je ne savais pas que cela était possible non plus, alors bravo à CSN
Hal
CS N ... Cela fonctionne pour moi, mais cela laisse la position centrale au mauvais endroit. Ma carte s'initialise comme la capture d'écran de l'OP, et c'est comme le centre: est centrée sur le coin supérieur gauche de ma map_canvas. Réflexions sur la façon de le centrer?
Kirk Ross
13

J'avais une carte Google dans un onglet Bootstrap, qui ne s'affichait pas correctement. C'était ma solution.

// Previously stored my map object(s) in googleMaps array

$('a[href="#profileTab"]').on('shown', function() {   // When tab is displayed...
    var map = googleMaps[0],
        center = map.getCenter();
    google.maps.event.trigger(map, 'resize');         // fixes map display
    map.setCenter(center);                            // centers map correctly
});
Simon Est
la source
1
J'ai dû remplacer «montré» par «shown.bs.tab» pour que cela fonctionne pour une carte qui était cachée dans un onglet inactif. Merci
Nicola
J'utilise SmartWizard 4 et c'est la seule solution qui a fonctionné pour moi et cela a très bien fonctionné! J'ai changé 'a[href="#profileTab"]'à ce step-2qui est le nom de la DIV contenant la carte DIV.
GeospatialPython.com
7

Comment actualiser la carte lorsque vous redimensionnez votre div

Il ne suffit pas d'appeler google.maps.event.trigger(map, 'resize');Vous devez également réinitialiser le centre de la carte.

var map;

var initialize= function (){
    ...
}

var resize = function () {
    if (typeof(map) == "undefined") {) {
        // initialize the map. You only need this if you may not have initialized your map when resize() is called.
        initialize();
    } else {
        // okay, we've got a map and we need to resize it
        var center = map.getCenter();
        google.maps.event.trigger(map, 'resize');
        map.setCenter(center);
    }
}

Comment écouter l'événement de redimensionnement

Angulaire (ng-show ou ui-bootstrap collapse)

Liez directement à la visibilité de l'élément plutôt qu'à la valeur liée à ng-show, car $ watch peut se déclencher avant que le ng-show ne soit mis à jour (ainsi le div sera toujours invisible).

scope.$watch(function () { return element.is(':visible'); },
    function () {
        resize();
    }
);

jQuery .show ()

Utilisez le rappel intégré

$("#myMapDiv").show(speed, function() { resize(); });

Bootstrap 3 Modal

$('#myModal').on('shown.bs.modal', function() {
    resize();
})
civmeup
la source
votre méthode de redimensionnement modal bootstrap 3 a parfaitement résolu mon problème, contrairement à la plupart des autres suggestions. Merci!
BrianLegg
6

Si vous avez inséré une carte Google Map en copiant / collant le code iframe et que vous ne souhaitez pas utiliser l'API Google Maps , c'est une solution simple. Exécutez simplement la ligne javascript suivante lorsque vous affichez la carte masquée. Il prend juste le code HTML iframe et l'insère au même endroit, donc il restitue:

document.getElementById("map-wrapper").innerHTML = document.getElementById("map-wrapper").innerHTML;

Version jQuery:

$('#map-wrapper').html( $('#map-wrapper').html() );

Le HTML:

....
<div id="map-wrapper"><iframe src="https://www.google.com/maps/..." /></div>
....

L'exemple suivant fonctionne pour une carte initialement masquée dans un onglet Bootstrap 3:

<script>
$(document).ready( function() {

    /* Detects when the tab is selected */
    $('a[href="#tab-id"]').on('shown.bs.tab', function() {

        /* When the tab is shown the content of the wrapper
           is regenerated and reloaded */

        $('#map-wrapper').html( $('#map-wrapper').html() ); 

    });
});
</script>
Gustavo
la source
2
Meilleure solution pour tous ceux qui ne chargent pas le Google Map JS mais utilisent simplement iframe avec l'URL srchttps://www.google.com/maps/embed/v1/place?..
gsinha
6

Il est également possible de simplement déclencher l'événement de redimensionnement de la fenêtre native.

Google Maps se rechargera automatiquement:

window.dispatchEvent(new Event('resize'));
Philippe
la source
5

J'ai eu le même problème, le google.maps.event.trigger(map, 'resize')ne fonctionnait pas pour moi.

Ce que j'ai fait, c'est de mettre un minuteur pour mettre à jour la carte après avoir mis le div...

//CODE WORKING

var refreshIntervalId;

function showMap() {
    document.getElementById('divMap').style.display = '';
    refreshIntervalId = setInterval(function () { updateMapTimer() }, 300);
}

function updateMapTimer() {
    clearInterval(refreshIntervalId);
    var map = new google.maps.Map(....
    ....
}

Je ne sais pas si c'est la façon la plus pratique de le faire mais ça marche!

Carlos
la source
utilisez setTimeout pour attendre une fois.
Joe Austin
4

Avec jQuery, vous pouvez faire quelque chose comme ça. Cela m'a aidé à charger une carte Google dans le CMS Umbraco sur un onglet qui ne serait pas visible tout de suite.

function waitForVisibleMapElement() {
    setTimeout(function () {
        if ($('#map_canvas').is(":visible")) {
            // Initialize your Google Map here
        } else {
            waitForVisibleMapElement();
        };
    }, 100);
};

waitForVisibleMapElement();
Dennis
la source
C'est la seule solution qui a fonctionné pour moi et mon problème. J'avais une carte google dans un onglet Materialise.CSS qui n'affichait pas la carte, mais qui montrait juste un arrière-plan gris avec uniquement le logo Marker et Google dans le coin gauche. J'ai défini le contenu de l'onglet div pour initialiser la carte lorsqu'elle est visible, et cela fonctionne parfaitement. Exemple
Gorgon_Union
3

Ma solution est très simple et efficace:

HTML

<div class="map-wrap"> 
  <div id="map-canvas"></div>
</div>


CSS

.map-wrap{
  height:0;
  width:0;
  overflow:hidden;
}


Jquery

$('.map-wrap').css({ height: 'auto', width: 'auto' }); //For showing your map
$('.map-wrap').css({ height: 0, width: 0 }); //For hiding your map
Midishero
la source
3

Ou si vous utilisez gmaps.js , appelez:

map.refresh();

lorsque votre div est affiché.

Eric Saboia
la source
2

Je suppose que la question originale concerne une carte qui est activée dans un div caché de la page. J'ai résolu un problème similaire en redimensionnant la carte dans le div caché lorsque le document est prêt, après son initialisation, quel que soit son état d'affichage. Dans mon cas, j'ai 2 cartes, une est affichée et une est cachée lorsqu'elles sont initialisées et je ne veux pas initialiser une carte à chaque fois qu'elle est affichée. C'est un ancien post, mais j'espère qu'il aidera tous ceux qui le recherchent.

KYLO
la source
2

J'ai trouvé que cela fonctionnait pour moi:

cacher:

$('.mapWrapper')
.css({
  visibility: 'hidden',
  height: 0
});

montrer:

    $('.mapWrapper').css({
      visibility: 'visible',
      height: 'auto'
    });
Victor S
la source
2

S'il est utilisé dans les onglets Bootstrap v3, les éléments suivants devraient fonctionner:

$('a[href="#tab-location"]').on('shown.bs.tab', function(e){
    var center = map.getCenter();
    google.maps.event.trigger(map, 'resize');
    map.setCenter(center);
});

tab-locationest l'ID de l'onglet contenant la carte.

Nirmal
la source
2

Tout comme John Doppelmann et HoffZ l'ont indiqué, rassemblez tout le code comme suit dans votre fonction d'affichage div ou événement onclick:

setTimeout(function(){
var center = map.getCenter();
google.maps.event.trigger(map, 'resize');
map.setCenter(center);
});

Cela a parfaitement fonctionné pour moi

Victor Tarango
la source
0

Ma solution était:

CSS:

.map {
   height: 400px;
   border: #ccc solid 1px;
}

jQuery:

$('.map').width(555); // width of map canvas
user2385294
la source
0

Je n'aimais pas que la carte se charge uniquement après que le div caché soit devenu visible. Dans un carrousel, par exemple, cela ne fonctionne pas vraiment.

Ma solution consiste à ajouter une classe à l'élément caché pour l'afficher et à le masquer avec une position absolue à la place, puis à rendre la carte et à supprimer la classe après le chargement de la carte.

Testé dans Bootstrap Carousel.

HTML

<div class="item loading"><div id="map-canvas"></div></div>

CSS

.loading { display: block; position: absolute; }

JS

$(document).ready(function(){
    // render map //
    google.maps.event.addListenerOnce(map, 'idle', function(){
        $('.loading').removeClass('loading');
    });
}

la source
0

utilisez cette ligne de codes lorsque vous souhaitez afficher la carte.

               $("#map_view").show("slow"); // use id of div which you want to show.
                    var script = document.createElement("script");
                    script.type = "text/javascript";
                    script.src = "https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&callback=initialize";
                    document.body.appendChild(script);
Ravi Darji
la source
0
 $("#map_view").show("slow"); // use id of div which you want to show.
     var script = document.createElement("script");
     script.type = "text/javascript";
     script.src = "https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&callback=initialize";
     document.body.appendChild(script);
Ravi Darji
la source
0

Premier poste. Mon div googleMap était dans un div conteneur avec {display: none} jusqu'au clic sur l'onglet. Eu le même problème que OP. Cela a fonctionné pour moi:

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

Collez ce code à l'intérieur et à la fin de votre code là où votre onglet de conteneur div est cliqué et révèle votre div caché. L'important est que votre conteneur div doit être visible avant que initialize puisse être appelé.

J'ai essayé un certain nombre de solutions proposées ici et d'autres pages et elles n'ont pas fonctionné pour moi. Faites-moi savoir si cela fonctionne pour vous. Merci.

Léonard
la source
0

Ajoutez ce code avant le div ou passez-le dans un fichier js:

<script>
    $(document).on("pageshow","#div_name",function(){
       initialize();
    });

   function initialize() {
   // create the map

      var myOptions = {
         zoom: 14,
         center: new google.maps.LatLng(0.0, 0.0),
         mapTypeId: google.maps.MapTypeId.ROADMAP
      }
      map = new google.maps.Map(document.getElementById("div_name"), myOptions);
   }


</script>

Cet événement sera déclenché après le chargement du div afin de rafraîchir le contenu de la carte sans avoir à appuyer sur F5

Balibrera
la source
0

Après avoir montré la carte, je géocoder une adresse puis définir le centre des cartes. Le google.maps.event.trigger(map, 'resize');n'a pas fonctionné pour moi.

J'ai dû utiliser un map.setZoom(14);

Code ci-dessous:

document.getElementById('map').style.display = 'block';
var geocoder = new google.maps.Geocoder();
        geocoder.geocode({ 'address': input.value }, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                map.setCenter(results[0].geometry.location);
                var marker2 = new google.maps.Marker({
                    map: map,
                    position: results[0].geometry.location
                });
                map.setZoom(14);
                marker2.addListener('dragend', function (event) {
                    $('#lat').val(event.latLng.lat());
                    $('#lng').val(event.latLng.lng());
                });

            }
        });
Andrew
la source
-1

function init_map() {
  var myOptions = {
    zoom: 16,
    center: new google.maps.LatLng(0.0, 0.0),
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  map = new google.maps.Map(document.getElementById('gmap_canvas'), myOptions);
  marker = new google.maps.Marker({
    map: map,
    position: new google.maps.LatLng(0.0, 0.0)
  });
  infowindow = new google.maps.InfoWindow({
    content: 'content'
  });
  google.maps.event.addListener(marker, 'click', function() {
    infowindow.open(map, marker);
  });
  infowindow.open(map, marker);
}
google.maps.event.addDomListener(window, 'load', init_map);

jQuery(window).resize(function() {
  init_map();
});
jQuery('.open-map').on('click', function() {
  init_map();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src='https://maps.googleapis.com/maps/api/js?v=3.exp'></script>

<button type="button" class="open-map"></button>
<div style='overflow:hidden;height:250px;width:100%;'>
  <div id='gmap_canvas' style='height:250px;width:100%;'></div>
</div>

user6414609
la source