como lidar com o google map dentro de uma div oculta (imagem atualizada)

127

Eu tenho uma página e um mapa do Google está dentro de uma div oculta em primeiro lugar. Em seguida, mostro a div depois de clicar em um link, mas apenas a parte superior esquerda do mapa aparece.

Eu tentei ter esse código executado após o clique:

    map0.onResize();

ou:

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

alguma ideia. Aqui está uma imagem do que vejo depois de mostrar a div com o mapa oculto.texto alternativo

leora
fonte
Já existe uma série de perguntas sobre o SO, incluindo a exibição do mapa do Google em uma área oculta
Matt Ball
@ Matt Ball - como atualizado, eu tentei adicionar o evento de redimensionamento lá, mas ainda não está funcionando
Leora
@ Matt Ball - eu consegui isso funcionar. Depois de criar o objeto do mapa do google, guardo isso em uma variável global para que eu possa referenciá-lo novamente mais tarde e chamar redimensionar agora parece funcionar. Estou tentando não ter que recriar o objeto de mapa toda vez que o mostro, porque permito que as pessoas alternem.
Leora
@ooo isso é muito simples com o código abaixo. Tudo o que você precisa adicionar é uma condição if para verificar se o objeto do mapa foi inicializado ou não. Este foi um código fora do manguito, escrito para resolver seu problema inicial, que é carregar o mapa corretamente.
Philar
@philar - yup. . obrigado aqui. . assim o voto positivo :). De qualquer maneira eu preciso para armazenar as variáveis em nível global para evitar reinitializing
Leora

Respostas:

103

Apenas testei e aqui está como eu me aproximei. Bem direto, deixe-me saber se você precisar de algum esclarecimento

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
fonte
Então, basicamente, você apenas instancia o mapa quando a div é mostrada? Existe alguma maneira de fazer isso para que o objeto do mapa seja instantâneo apenas uma vez (no carregamento da página)?
Lucas
1
Eu também poderia sugerir um atraso de setTimeout para chamar a segunda função se você estiver chamando um show () para permitir tempo para redimensionar.
Eric.18
126

Eu estava tendo o mesmo problema e descobri que, quando mostra o div, chame google.maps.event.trigger(map, 'resize');e ele parece resolver o problema para mim.

Eric
fonte
64
Para manter o centro original do mapa logo após o redimensionamento, considere estender a instrução de redimensionamento da seguinte maneira: var center = map.getCenter (); google.maps.event.trigger (mapa, 'redimensionar'); map.setCenter (centro);
John Doppelmann
10
Não sei por que, mas preciso agrupar a solução dentro do pequeno setTimeout para que ele funcione: setTimeout (function () {google.maps.event.trigger (map, 'redimensionar')}, 100);
HoffZ 27/02
@JohnDoppelmann Obrigado pela dica! Não era intuitivo por que não estava mantendo o centro, nem como forçá-lo de volta.
Noah Duncan
Defina o centro do mapa e o nível de zoom novamente após acionar o evento 'redimensionar'. Para mais informações, consulte: code.google.com/p/gmaps-api-issues/issues/detail?id=1448
ruhong
@HoffZ isso provavelmente se deve ao fato de o código de redimensionamento ser disparado antes do efeito de exibição, o tempo limite atrasa até a exibição do show, e o redimensionamento pode dar certo. Você provavelmente pode conseguir o mesmo efeito alterando sua ordem de execução do código para garantir que, ao disparar o evento, a exibição de div seja executada antes do redimensionamento do mapa.
Bardo
26
google.maps.event.trigger($("#div_ID")[0], 'resize');

Se você não possui um mapa variável disponível, ele deve ser o primeiro elemento (a menos que você tenha feito algo estúpido) no divque contém GMAP.

CSN
fonte
Tem certeza de que pode disparar o elemento em uma div em vez de em um objeto google.map.Map ?
Salman Um
@ SalmanA - Acabei de verificar isso e funcionou para mim (embora o mapa pareça ter um novo centro). De pesquisas anteriores, eu não sabia que isso era possível, ou seja, parabéns à CSN
Hal
CS N ... Isso funciona para mim, mas deixa a posição central no lugar errado. Meu mapa está inicializando como a captura de tela do OP, e é como o centro: está centralizado no canto superior esquerdo do meu map_canvas. Pensamentos sobre como fazê-lo desenhar centrado?
Kirk Ross
13

Eu tinha um mapa do Google dentro de uma guia Bootstrap, que não estava sendo exibida corretamente. Esta foi a minha correção.

// 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 East
fonte
1
Eu tive que substituir 'mostrado' por 'mostrado.bs.tab' para fazer isso funcionar para um mapa que estava oculto em uma guia inativa. Obrigado
Nicola
Estou usando o SmartWizard 4 e esta é a única solução que funcionou para mim e funcionou muito bem! Mudei 'a[href="#profileTab"]'para step-2qual é o nome do DIV que contém o mapa DIV.
GeospatialPython.com
7

Como atualizar o mapa quando você redimensiona sua div

Não basta apenas ligar. google.maps.event.trigger(map, 'resize');Você deve redefinir o centro do mapa também.

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

Como ouvir o evento de redimensionamento

Angular (recolhimento de ng-show ou ui-bootstrap)

Vincule diretamente à visibilidade do elemento, e não ao valor vinculado ao ng-show, porque o $ watch pode disparar antes que o ng-show seja atualizado (para que a div ainda fique invisível).

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

jQuery .show ()

Use o retorno de chamada incorporado

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

Bootstrap 3 Modal

$('#myModal').on('shown.bs.modal', function() {
    resize();
})
civmeup
fonte
seu método de redimensionamento modal do bootstrap 3 corrigiu meu problema perfeitamente, enquanto a maioria das outras sugestões não. Obrigado!
BrianLegg
6

Se você tem um Google Map inserido copiando / colando o código iframe e não deseja usar a API do Google Maps , esta é uma solução fácil. Basta executar a seguinte linha javascript quando você mostrar o mapa oculto. Ele pega o código HTML do iframe e o insere no mesmo local, tornando-o novamente:

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

Versão jQuery:

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

O HTML:

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

O exemplo a seguir funciona para um mapa inicialmente oculto na guia 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
fonte
2
Melhor solução para quem não está a carregar o Google Map JS, mas simplesmente usando iframe com url srchttps://www.google.com/maps/embed/v1/place?..
gsinha
6

Também é possível disparar o evento de redimensionamento da janela nativa.

O Google Maps será recarregado automaticamente:

window.dispatchEvent(new Event('resize'));
Philip
fonte
5

Eu tive o mesmo problema, o google.maps.event.trigger(map, 'resize')não estava funcionando para mim.

O que fiz foi colocar um cronômetro para atualizar o mapa depois de colocar visível o 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(....
    ....
}

Não sei se é a maneira mais conveniente de fazer isso, mas funciona!

Carlos
fonte
use setTimeout para aguardar uma vez.
30515 Joe Joe as
4

Com o jQuery, você pode fazer algo assim. Isso me ajudou a carregar um mapa do Google no Umbraco CMS em uma guia que não seria visível imediatamente.

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

waitForVisibleMapElement();
Dennis
fonte
Esta é a única solução que funcionou para mim e meu problema. Eu tinha um mapa do google dentro de uma guia Materialize.CSS que não mostrava o mapa, mas mostrava apenas um fundo cinza com apenas o marcador e o logotipo do Google no canto esquerdo. Defino a div content da guia para inicializar o mapa quando visível, e ele funciona perfeitamente. Exemplo
Gorgon_Union
3

Minha solução é muito simples e eficiente:

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

Ou, se você usa o gmaps.js , ligue para:

map.refresh();

quando sua div é mostrada.

Eric Saboia
fonte
2

Eu acho que a pergunta original é com um mapa que é inicializado em uma div oculta da página. Resolvi um problema semelhante redimensionando o mapa na div oculta após o documento estar pronto, depois que ele foi inicializado, independentemente do status de exibição. No meu caso, eu tenho 2 mapas, um é mostrado e outro é oculto quando eles são inicializados e não quero inicializar um mapa toda vez que é mostrado. É um post antigo, mas espero que ajude quem estiver procurando.

KYLO
fonte
2

Descobri que isso funciona para mim:

esconder:

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

mostrar:

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

Se usado nas guias do Bootstrap v3, o seguinte deve funcionar:

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

onde tab-locationé o ID da guia que contém o mapa.

Nirmal
fonte
2

Assim como John Doppelmann e HoffZ indicaram, monte todo o código da seguinte maneira na sua função de exibição de div ou no evento onclick:

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

Funcionou perfeitamente para mim

Victor Tarango
fonte
0

Minha solução foi:

CSS:

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

jQuery:

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

Não gostei que o mapa fosse carregado apenas depois que a div oculta se tornasse visível. Em um carrossel, por exemplo, isso realmente não funciona.

Essa é a minha solução é adicionar classe ao elemento oculto para exibi-lo e ocultá-lo com a posição absoluta, renderize o mapa e remova a classe após o carregamento do mapa.

Testado no carrossel de bootstrap.

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

fonte
0

use esta linha de códigos quando quiser mostrar o mapa.

               $("#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
fonte
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
fonte
0

Primeiro post. Minha div do googleMap estava dentro de uma div de contêiner com {display: none} até a guia ser clicada. Teve o mesmo problema que OP. Isso funcionou para mim:

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

Cole esse código dentro e no final do seu código, onde a guia div do contêiner é clicada e revela sua div oculta. O importante é que sua div de contêiner tenha que estar visível antes que a inicialização possa ser chamada.

Tentei várias soluções propostas aqui e em outras páginas e elas não funcionaram para mim. Deixe-me saber se isso funciona para você. Obrigado.

Leonard
fonte
0

Adicione este código antes da div ou passe-o para um arquivo 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>

Este evento será acionado após o carregamento da div, para atualizar o conteúdo do mapa sem precisar pressionar F5

Balibrera
fonte
0

Ao mostrar o mapa, estou geocodificando um endereço e definindo o centro dos mapas. ogoogle.maps.event.trigger(map, 'resize'); não funcionou para mim.

Eu tive que usar um map.setZoom(14);

Código abaixo:

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