TypeError da API do Google MAP não detectado: não é possível ler a propriedade 'offsetWidth' de null

204

Estou tentando usar a API do Google MAP v3 com o seguinte código.

<h2>Topology</h2>

<script src="https://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>

<link rel="stylesheet" type="text/css" href="{% url css_media 'tooltip.topology.css' %}" />
<link rel="stylesheet" type="text/css" href="{% url css_media 'tooltip.css' %}" />

<style type="text/css" >
      #map_canvas {
              width:300px;
            height:300px;
     }
</style>

<script type="text/javascript">

var latlng = new google.maps.LatLng(-34.397, 150.644);
var myOptions = {
zoom: 8,
      center: latlng,
      mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"),
            myOptions);

</script>

<div id="map_canvas"> </div>

Quando executo esse código, o navegador diz isso.

TypeError não capturado: Não é possível ler a propriedade 'offsetWidth' de null

Não faço ideia, pois sigo a orientação dada neste tutorial .

Faz alguma ideia?

jaeyong
fonte

Respostas:

317

Esse problema geralmente ocorre porque a div do mapa não é renderizada antes da execução do javascript que precisa acessá-lo.

Você deve colocar seu código de inicialização em uma função onload ou na parte inferior do arquivo HTML, imediatamente antes da tag, para que o DOM seja completamente renderizado antes de ser executado (observe que a segunda opção é mais sensível ao HTML inválido).

Observe que, como apontado pelas matthewsheets, isso também pode ser causado pelo div com esse ID inexistente no seu HTML (o caso patológico do div não sendo renderizado)

Adicionando amostra de código da postagem de wf9a5m75 para colocar tudo em um só lugar:

<script type="text/javascript">

function initialize() {
    var latlng = new google.maps.LatLng(-34.397, 150.644);
    var myOptions = {
        zoom: 8,
        center: latlng,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    var map = new google.maps.Map(document.getElementById("map_canvas"),
            myOptions);
}
google.maps.event.addDomListener(window, "load", initialize);

</script>
geocodezip
fonte
7
Isso acontece comigo o tempo todo quando esqueço de condicionalizar meu script de mapas. Adicionando: var mapExists = document.getElementById ("map-canvas"); if (mapExists) {// script} melhora tudo.
Imperativo imperativo
109

Para outras pessoas que ainda podem ter esse problema , mesmo depois de tentar as recomendações acima, o uso de um seletor incorreto para a tela do mapa na função de inicialização pode causar o mesmo problema, pois a função está tentando acessar algo que não existe. Verifique duas vezes se o ID do seu mapa corresponde à sua função de inicialização e se o seu HTML ou esse mesmo erro podem ser exibidos.

Em outras palavras, verifique se seus IDs correspondem. ;)

matthewsheets
fonte
3
Incrível como você pode ter tanta certeza de que esse não é o problema ... até você checar e perceber que o alterou nos testes anteriores e esqueceu de mudar novamente. :-)
Charlie Gorichanaz
28

Você também pode receber esse erro se não especificar centerou zoomnas opções do seu mapa.

JamesFrost
fonte
2
Essa foi a única! Removido o zoom das opções, já que eu o definia posteriormente no script, e, boom, o mapa carregaria na primeira vez, mas na segunda vez geraria esse erro. Obrigado!!
Iain Grant
Sim, isso era meu! Tinha um zoom, mas nenhum centro. Basta adicionar o centro para consertá-lo.
Whelkaholism
1
Eles poderiam ter registrado alguma mensagem no console, pelo menos, realmente. Obrigado!
Martin Shishkov
26

o google usa id="map_canvas"e id="map-canvas"nas amostras, verifique novamente e verifique novamente o id: D

dpineda
fonte
23

Ano, a resposta de geocodezip está correta. Então, mude seu código assim: (se você ainda estiver com problemas, ou talvez outra pessoa no futuro)

<script type="text/javascript">

function initialize() {
    var latlng = new google.maps.LatLng(-34.397, 150.644);
    var myOptions = {
        zoom: 8,
        center: latlng,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    var map = new google.maps.Map(document.getElementById("map_canvas"),
            myOptions);
}
google.maps.event.addDomListener(window, "load", initialize);

</script>
wf9a5m75
fonte
Exatamente, primeiro renderize a div html e, em seguida, o JS adicione um ouvinte de evento.
foxybagga
11

Só para adicionar meu cenário de falha ao fazer isso funcionar. Eu tinha um <div id="map>no qual estava carregando o mapa:

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

e a div foi ocultada inicialmente e não tinha explicitamente os valores de largura e altura definidos, portanto o tamanho era width x 0. Depois de definir o tamanho dessa div em CSS assim

#map {
    width: 500px;
    height: 300px;
}

tudo funcionou! Espero que isso ajude alguém.

Nikola
fonte
Esta foi exatamente a razão pela qual não funcionou para mim. Você precisa garantir que o CSS corresponda ao seu ID do mapa e que você tenha algum tipo de combinação largura / altura inicial, caso contrário, nada será renderizado. Então, para recapitular: 1. verifique se o seu html div id corresponde ao seletor de ID ao chamar getElementById no JavaScript 2. verifique se o CSS possui código para estilizar seu mapa específico, por exemplo, # map1 {width: 200px; altura: 200 px; } ou similar, para renderizar.
Tahir Khalid 28/07
7

Para ainda mais pessoas que ainda podem estar tendo esse problema, eu estava usando uma <div id="map1" />tag de fechamento automático , e a segunda div não estava aparecendo e não parecia estar no domínio. Assim que eu mudei para duas tags de abertura e fechamento <div id="map1"></div>, funcionou. hth

changokun
fonte
6

Também tome cuidado para não escrever

google.maps.event.addDomListener(window, "load", init())

corrigir:

google.maps.event.addDomListener(window, "load", init)
Mike
fonte
De fato. Isso também foi um problema no meu caso. O primeiro executa a função init imediatamente quando o segundo passa a função init como um parâmetro para o ouvinte de eventos, que executará a função init quando esse evento ocorrer. stackoverflow.com/questions/13286233/...
kivikall
6

Eu tinha aspas simples na minha

var map = new google.maps.Map( document.getElementById('map_canvas') );

e os substituiu por aspas duplas

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

Isso fez o truque para mim.

Programador VB.Net
fonte
5

Alterar o ID (em todos os 3 lugares) de "map-canvas" para "map" o corrigiu para mim, mesmo que eu tivesse certeza de que os IDs eram os mesmos, a div tinha largura e altura, e o código não era funcionando até após a chamada de carregamento da janela. Não é o traço; parece não funcionar com outro ID que não seja "map".

Johnny5k
fonte
4

Além disso, verifique se você não está colocando o símbolo de hash (#) dentro do seletor em um

    document.getElementById('#map') // bad

    document.getElementById('map') // good

declaração. Não é um jQuery. Apenas um lembrete rápido para alguém com pressa.

Keeprock
fonte
3

Eu tive o mesmo problema, mas o problema era que o zoom não estava definido no objeto de opções fornecido ao Google Maps.

torresomar
fonte
2

Se você estiver criando vários mapas em um loop, se um único elemento DOM do mapa não existir, ele quebrará todos eles. Primeiro, verifique se o elemento DOM existe antes de criar um novo objeto Map.

[...]

for( var i = 0; i <= self.multiple_maps; i++ ) {

  var map_element = document.getElementById( 'map' + '-' + i.toString() );

  // Element doesn't exist, don't create map!
  if( null === map_element ) {
    continue;
  }

  var map = new google.maps.Map( map_element, myOptions);
}

[...]
Zack Katz
fonte
1
Mas tudo o que faz é impedir que o mapa seja criado, na verdade não consertando a bagunça e criando o mapa.
Ryan The Leach
1

Se você estiver usando Webforms do asp.net e estiver registrando o script no código atrás de uma página usando uma página mestre, não se esqueça de usar o ID do cliente do elemento do mapa (vb.net):

ClientScript.RegisterStartupScript(Me.[GetType](), "Google Maps Initialization", String.Format("init_map(""" & map_canvas.ClientID() & """...
Winks
fonte
1

Para resolvê-lo, você precisa adicionar async deferao script.

Deve ser assim:

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"
    async defer></script>

Veja aqui o significado do adiamento assíncrono.

Como você chamará uma função a partir do arquivo js principal, também deseje ter certeza de que é após a onde você carrega o script principal.

Avi Levin
fonte
1

Certifique-se de incluir o &libraries=placesparâmetro da biblioteca do Google Places ao carregar a API pela primeira vez.

Por exemplo:

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places">
Steve
fonte
1

Eu sei que estou um pouco atrasado para a festa, só queria acrescentar que o erro também pode acontecer quando a div não existe na página. Você também pode verificar se a div existe primeiro antes de carregar a chamada de função do Google Maps. Algo como

function initMap() {
    if($("#venuemap").length != 0) {
        var city= {lat: -26.2041, lng: 28.0473};
        var map = new google.maps.Map(document.getElementById('venuemap'), {
       etc etc
     }
}
mr_j
fonte
1
  • Configure ng-init = init () no seu HTML
  • E no controlador

    use $ scope.init = function () {...} em vez de google.maps.event.addDomListener (janela, "carregar", init) {...}

Espero que isso ajude você.

Akash Saxena
fonte
0

Na verdade, a maneira mais fácil de corrigir isso é mover o seu objeto antes que o código Javascript funcionasse para mim. Eu acho que na sua resposta objeto é carregado após o código javascript.

<style type="text/css" >
      #map_canvas {
              width:300px;
            height:300px;
     }

 <div id="map_canvas"> </div> // Here 

<script type="text/javascript">

var latlng = new google.maps.LatLng(-34.397, 150.644);
var myOptions = {
zoom: 8,
      center: latlng,
      mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"),
            myOptions);

</script>

<div id="map_canvas"> </div>
Laltzi
fonte
0

No meu caso, esses tipos de problemas foram resolvidos usando defer https://developer.mozilla.org/en/docs/Web/HTML/Element/script

<script src="<your file>.js" defer></script>

Você precisa levar em conta o suporte dos navegadores a essa opção (não vi problemas)

Yercalamarino
fonte
0

Verifique se você não está substituindo window.self

Meu problema: criei um componente e escrevi em self = thisvez de var self = this. Se você não usar a palavra-chave var, o JS colocará essa variável no objeto da janela, então substitui o window.selfque causou esse erro.

Mike R Emo
fonte
0

Esta é uma edição de uma postagem excluída anteriormente para conter o conteúdo da resposta vinculada, na própria resposta. O objetivo de republicar esta resposta é funcionar como um PSA para usuários do React 0.9+ que também se depararam com esse problema.

postagem editada original


Também recebi esse erro ao usar o ReactJS ao seguir esta postagem do blog . O comentário de sahat aqui ajudou - veja o conteúdo do comentário de sahat abaixo.

❗️ Nota para Reagir> = 0.9

Antes da v0.9, o nó DOM era passado como o último argumento. Se você estava usando isso, ainda pode acessar o nó DOM chamando this.getDOMNode ().

Em outras palavras, substitua o parâmetro rootNode por this.getDOMNode () na versão mais recente do React.

Meredith
fonte
0

Minha falha foi usar

zoomLevel

como uma opção, em vez da opção correta

zoom
Strattonn
fonte
0

adicione adiamento assíncrono no início da chamada de chave da API do mapa.

Ghadir Farzaneh
fonte
0

No caso em que eu estava lidando, a div do mapa era renderizada condicionalmente, dependendo se o local estava sendo tornado público. Se você não tiver certeza se a div da tela do mapa estará na página, verifique se você document.getElementByIdestá retornando um elemento e invoque o mapa apenas se estiver presente:

var mapEle = document.getElementById("map_canvas");
if (mapEle) {
    map = new google.maps.Map(mapEle, myOptions);
}
Rillus
fonte
-2

Aqui o problema era o link da API sem o keyparâmetro:

<script type="text/javascript" src="http://maps.google.com/maps/api/js?libraries=places&key=YOURKEY"></script>

Dessa forma, funciona bem.

vaati
fonte