come gestire google map all'interno di un div nascosto (immagine aggiornata)


127

ho una pagina e una google map è inizialmente all'interno di un div nascosto. Quindi visualizzo il div dopo aver fatto clic su un collegamento, ma viene visualizzato solo l'angolo in alto a sinistra della mappa.

ho provato a far eseguire questo codice dopo il clic:

    map0.onResize();

o:

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

qualche idea. ecco un'immagine di ciò che vedo dopo aver mostrato il div con la mappa nascosta in esso.testo alternativo


Ci sono già una serie di domande su SO a riguardo, tra cui la visualizzazione della mappa di Google da un'area nascosta
Matt Ball

@Matt Ball - come aggiornato, ho provato ad aggiungere l'evento di ridimensionamento lì ma ancora non funziona
leora

@Matt Ball - l'ho fatto funzionare. dopo aver creato l'oggetto google map, lo memorizzo in una variabile globale in modo da poterlo fare nuovamente riferimento in seguito e chiamare il ridimensionamento ora sembra funzionare. Sto cercando di non dover ricreare l'oggetto mappa ogni volta che lo mostro perché consento alle persone di alternare avanti e indietro.
leora,

@ooo che è molto semplice con il codice qui sotto. È sufficiente aggiungere una condizione if per verificare se l'oggetto mappa è stato inizializzato o meno. Si trattava di un codice predefinito scritto per risolvere il problema iniziale che consiste nel caricare correttamente la mappa.
Philar,

@philar - yup. . grazie qui. . quindi il voto :). In entrambi i casi
devo

Risposte:


103

L'ho provato da solo ed ecco come l'ho affrontato. Abbastanza diretto, fammi sapere se hai bisogno di chiarimenti

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>

Quindi fondamentalmente si crea un'istantanea della mappa solo quando viene mostrato il div? Esiste un modo per eseguire questa operazione in modo che l'oggetto mappa venga istanziato una sola volta (al caricamento della pagina)?
Lucas,

1
Potrei anche suggerire un ritardo setTimeout per chiamare la seconda funzione se stai chiamando uno show () per consentire il tempo di ridimensionare.
Eric.18

126

Stavo avendo lo stesso problema e ho scoperto che quando mostra il div, chiama google.maps.event.trigger(map, 'resize');e sembra che risolva il problema per me.


64
Per mantenere il centro originale della mappa subito dopo il ridimensionamento, prendere in considerazione l'estensione dell'istruzione di ridimensionamento in questo modo: var center = map.getCenter (); google.maps.event.trigger (mappa, 'ridimensiona'); map.setCenter (centro);
John Doppelmann,

10
Non so perché, ma ho bisogno di avvolgere la soluzione all'interno di piccoli setTimeout per farlo funzionare: setTimeout (function () {google.maps.event.trigger (map, 'resize')}, 100);
HoffZ,

@JohnDoppelmann Grazie per l'informazione! Non era intuitivo il motivo per cui non manteneva il centro, né come forzarlo.
Noah Duncan,

Imposta di nuovo il centro della mappa e il livello di zoom dopo aver attivato l'evento 'ridimensiona'. Per ulteriori informazioni, consultare: code.google.com/p/gmaps-api-issues/issues/detail?id=1448
ruhong

@HoffZ questo è probabilmente dovuto al licenziamento del codice di ridimensionamento prima dell'effetto show, il timeout lo ritarda fino a quando non viene eseguito lo show, quindi il ridimensionamento può farlo funzionare. Probabilmente puoi ottenere lo stesso effetto modificando l'ordine di esecuzione del codice per assicurarti che quando si attiva l'evento, la visualizzazione div venga eseguita prima del ridimensionamento della mappa.
Bardo,

26
google.maps.event.trigger($("#div_ID")[0], 'resize');

Se non hai a disposizione una mappa variabile, dovrebbe essere il primo elemento (a meno che tu non abbia fatto qualcosa di stupido) in quello divche contiene GMAP.


Sei sicuro di poter attivare l'elemento su un div anziché un oggetto google.map.Map ?
Salman,

@SalmanA - Ho appena controllato questo e ha funzionato per me (anche se la mappa sembra avere un nuovo centro). Da ricerche precedenti non sapevo che questo fosse possibile, quindi complimenti a CSN
Hal

CS N ... Questo funziona per me, ma lascia la posizione centrale nel punto sbagliato. La mia mappa si sta inizializzando come la schermata dell'OP, ed è come il centro: è centrato nell'angolo in alto a sinistra dei miei map_canvas. Pensi su come farlo centrare?
Kirk Ross,

13

Avevo una mappa di Google all'interno di una scheda Bootstrap, che non veniva visualizzata correttamente. Questa era la mia soluzione.

// 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
});

1
Ho dovuto sostituire "illustrato" in "illustrato.bs.tab" per farlo funzionare per una mappa che era nascosta in una scheda inattiva. Grazie
Nicola,

Sto usando SmartWizard 4 e questa è l'unica soluzione che ha funzionato per me e ha funzionato alla grande! Ho cambiato 'a[href="#profileTab"]'in step-2quale è il nome del DIV contenente la mappa DIV.
GeospatialPython.com il

7

Come aggiornare la mappa quando ridimensioni il tuo div

Non è sufficiente solo chiamare google.maps.event.trigger(map, 'resize');Dovresti ripristinare anche il centro della mappa.

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);
    }
}

Come ascoltare l'evento di ridimensionamento

Angolare (ng-show o ui-bootstrap collapse)

Associa direttamente alla visibilità dell'elemento piuttosto che al valore associato a ng-show, perché $ watch può attivarsi prima che venga aggiornato ng-show (quindi il div sarà comunque invisibile).

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

jQuery .show ()

Utilizzare il callback integrato

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

Bootstrap 3 modale

$('#myModal').on('shown.bs.modal', function() {
    resize();
})

il tuo metodo di ridimensionamento modale bootstrap 3 ha risolto perfettamente il mio problema, mentre la maggior parte degli altri suggerimenti no. Grazie!
BrianLegg,

6

Se hai inserito una mappa di Google copiando / incollando il codice iframe e non desideri utilizzare l'API di Google Maps , questa è una soluzione semplice. Basta eseguire la seguente riga javascript quando si mostra la mappa nascosta. Prende solo il codice HTML iframe e lo inserisce nello stesso posto, quindi esegue nuovamente il rendering:

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

versione jQuery:

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

HTML:

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

L'esempio seguente funziona per una mappa inizialmente nascosta in una scheda 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>

2
La migliore soluzione per chiunque non stia caricando Google Map JS ma semplicemente usando iframe con src urlhttps://www.google.com/maps/embed/v1/place?..
gsinha

6

È anche possibile attivare l'evento di ridimensionamento della finestra nativa.

Google Maps si ricaricherà automaticamente:

window.dispatchEvent(new Event('resize'));

5

Ho avuto lo stesso problema, google.maps.event.trigger(map, 'resize')non funzionava per me.

Quello che ho fatto è stato mettere un timer per aggiornare la mappa dopo aver reso visibile il 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(....
    ....
}

Non so se sia il modo più conveniente per farlo ma funziona!


usa setTimeout per aspettare una volta.
Joe Austin,

4

Con jQuery potresti fare qualcosa del genere. Questo mi ha aiutato a caricare una Google Map in Umbraco CMS in una scheda che non sarebbe stata visibile da subito.

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

waitForVisibleMapElement();

Questa è l'unica soluzione che ha funzionato per me e il mio problema. Avevo una mappa di google all'interno di una scheda Materialise.CSS che non mostrava la mappa, ma mostrava solo uno sfondo grigio con solo il marcatore e il logo di Google nell'angolo sinistro. Ho impostato il div del contenuto della scheda per inizializzare la mappa quando è visibile e funziona perfettamente. Esempio
Gorgon_Union

3

La mia soluzione è molto semplice ed efficiente:

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


2

Immagino che la domanda originale sia con una mappa che è initalizzata in un div nascosto della pagina. Ho risolto un problema simile ridimensionando la mappa nel div nascosto al momento del documento pronto, dopo che è stato inizializzato, indipendentemente dal suo stato di visualizzazione. Nel mio caso, ho 2 mappe, una è mostrata e una è nascosta quando sono inizializzate e non voglio inizializzare una mappa ogni volta che viene mostrata. È un vecchio post, ma spero che aiuti chiunque cerchi.


2

Ho trovato che questo funziona per me:

nascondere:

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

mostrare:

    $('.mapWrapper').css({
      visibility: 'visible',
      height: 'auto'
    });

2

Se utilizzato nelle schede Bootstrap v3, dovrebbe funzionare come segue:

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

dove si tab-locationtrova l'ID della scheda contenente la mappa.


2

Proprio come hanno indicato John Doppelmann e HoffZ, metti insieme tutto il codice proprio come segue nella tua div che mostra la funzione o l'evento onclick:

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

Ha funzionato perfettamente per me


0

La mia soluzione era:

CSS:

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

jQuery:

$('.map').width(555); // width of map canvas

0

Non mi piaceva che la mappa si caricasse solo dopo che il div nascosto era diventato visibile. In una giostra, ad esempio, non funziona davvero.

Questa mia soluzione è aggiungere classe all'elemento nascosto per scoprirlo e nasconderlo con la posizione assoluta, quindi eseguire il rendering della mappa e rimuovere la classe dopo il caricamento della mappa.

Testato in 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');
    });
}

0

usa questa linea di codici quando vuoi mostrare la mappa.

               $("#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);

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);

0

Primo post. Il mio div googleMap era all'interno di un contenitore div con {display: none} fino a quando non si faceva clic sulla scheda. Ha avuto lo stesso problema di OP. Questo ha funzionato per me:

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

Inserisci questo codice all'interno e alla fine del codice in cui si fa clic sulla scheda div del contenitore e rivela il div nascosto. L'importante è che il div container sia visibile prima di poter chiamare l'inizializzazione.

Ho provato una serie di soluzioni proposte qui e in altre pagine e non hanno funzionato per me. Fammi sapere se questo funziona per te. Grazie.


0

Aggiungi questo codice prima del div o passalo a un file 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>

Questo evento verrà attivato dopo il caricamento del div, quindi aggiornerà il contenuto della mappa senza dover premere F5


0

Dopo aver mostrato la mappa, sto geocodificando un indirizzo, quindi impostando il centro mappe. Il google.maps.event.trigger(map, 'resize');non ha funzionato per me.

Ho dovuto usare a map.setZoom(14);

Codice sotto:

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());
                });

            }
        });

-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>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.