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?

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>

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


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.


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


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>

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.


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


6

Também tome cuidado para não escrever

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

corrigir:

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

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.


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


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.


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.


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

[...]

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() & """...

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.


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

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

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


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>


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.


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.


0

Minha falha foi usar

zoomLevel

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

zoom


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

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.