Error de tipo de API de Google MAP no detectado: no se puede leer la propiedad 'offsetWidth' de nulo

204

Estoy tratando de usar Google MAP API v3 con el siguiente 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>

Cuando ejecuto este código, el navegador dice esto.

TypeError no capturado: no se puede leer la propiedad 'offsetWidth' de nulo

No tengo idea, ya que sigo las instrucciones dadas en este tutorial .

¿Tienes alguna pista?

jaeyong
fuente

Respuestas:

317

Este problema generalmente se debe a que el div de mapa no se representa antes de que se ejecute JavaScript que necesita acceder a él.

Debe colocar su código de inicialización dentro de una función de carga o en la parte inferior de su archivo HTML, justo antes de la etiqueta, para que el DOM se procese completamente antes de ejecutarse (tenga en cuenta que la segunda opción es más sensible a HTML no válido).

Tenga en cuenta que, como se señala en matthewsheets, esto también podría ser causado por el div con esa identificación que no existe en absoluto en su HTML (el caso patológico del div no se representa)

Agregar código de muestra de la publicación de wf9a5m75 para poner todo en un solo 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
fuente
77
Esto me sucede todo el tiempo cuando olvido condicionalizar mi script de mapas. Agregando: var mapExists = document.getElementById ("map-canvas"); if (mapExists) {// script} lo hace todo mejor.
Imperativo
109

Para otros que todavía pueden tener este problema , incluso después de probar las recomendaciones anteriores, usar un selector incorrecto para el lienzo del mapa en la función de inicialización puede causar el mismo problema ya que la función está intentando acceder a algo que no existe. Vuelva a verificar que su ID de mapa coincida con su función de inicialización y su HTML o este mismo error puede ser arrojado.

En otras palabras, asegúrese de que sus ID coincidan. ;)

hojas de matthews
fuente
3
Es sorprendente cómo puede estar tan seguro de que este no es el problema ... hasta que verifique dos veces y se dé cuenta de que lo cambió antes de las pruebas y olvidó volver a cambiarlo. :-)
Charlie Gorichanaz
28

También puede obtener este error si no especifica centero zoomen sus opciones de mapa.

JamesFrost
fuente
2
Ese fue el! Se eliminó el zoom de las opciones ya que lo estaba configurando más adelante en el script de todos modos, y boom, el mapa se cargaría la primera vez, pero la segunda generaría ese error. ¡¡Gracias!!
Iain Grant
Sí, esto era mío! Tenía un zoom pero no centro. Simplemente agregando el centro lo arregló.
Whelkaholism
1
Podrían haber registrado algún mensaje en la consola al menos, de verdad. ¡Gracias!
Martin Shishkov
26

google usa id="map_canvas"y id="map-canvas"en las muestras, verifique y vuelva a verificar la identificación: D

dpineda
fuente
23

Año, la respuesta de geocodezip es correcta. Así que cambie su código de esta manera: (si todavía tiene problemas, o tal vez alguien más en el 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
fuente
Exactamente, primero renderice el div html y luego el JS más agregue un detector de eventos.
foxybagga
11

Solo así que agrego mi escenario de falla para que esto funcione. Tenía un <div id="map>en el que estaba cargando el mapa con:

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

y el div estaba inicialmente oculto y no tenía valores de ancho y alto explícitamente establecidos, por lo que su tamaño era width x 0. Una vez que he establecido el tamaño de este div en CSS como este

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

todo funcionó! Espero que esto ayude a alguien.

Nikola
fuente
Esta fue exactamente la razón por la que no funcionó para mí. Debe asegurarse de que el CSS coincida con su ID de mapa y de que tenga algún tipo de combo de ancho / alto inicial, de lo contrario no se representará nada. Para recapitular: 1. asegúrese de que su id div html coincida con el selector de id cuando llame a getElementById en su JavaScript 2. asegúrese de que el CSS tenga un código para diseñar su mapa en particular, por ejemplo, # map1 {ancho: 200px; altura: 200 px; } o similar para que se procese.
Tahir Khalid
7

Para aún más personas que aún podrían tener este problema, estaba usando una <div id="map1" />etiqueta de cierre automático , y el segundo div no se mostraba, y no parecía estar en el dom. tan pronto como lo cambié a dos etiquetas de abrir y cerrar <div id="map1"></div>, funcionó. hth

changokun
fuente
6

También ten cuidado de no escribir

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

correcto:

google.maps.event.addDomListener(window, "load", init)
Miguel
fuente
En efecto. Ese fue un problema en mi caso también. El primero ejecuta la función init de inmediato cuando el segundo simplemente pasa la función init como parámetro al detector de eventos que ejecutará la función init cuando ocurra ese evento. stackoverflow.com/questions/13286233/…
kivikall
6

Tenía comillas simples en mi

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

y los reemplazó con comillas dobles

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

Esto hizo el truco para mí.

Programador VB.Net
fuente
5

El cambio de la ID (en los 3 lugares) de "map-canvas" a "map" lo arregló para mí, aunque me había asegurado de que las ID fueran las mismas, el div tenía un ancho y una altura, y el código no era funcionando hasta después de la llamada de carga de la ventana. No es el guión; no parece funcionar con ninguna otra identificación que no sea "mapa".

Johnny5k
fuente
4

Además, asegúrese de no colocar el símbolo hash (#) dentro de su selector en un

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

    document.getElementById('map') // good

declaración. No es un jQuery. Solo un recordatorio rápido para alguien que tiene prisa.

Keeprock
fuente
3

Tuve el mismo problema, pero el problema era que el zoom no estaba definido dentro del objeto de opciones dado a Google Maps.

torresomar
fuente
2

Si está creando múltiples mapas en un bucle, si no existe un solo elemento DOM de mapa, los rompe a todos. Primero, verifique para asegurarse de que el elemento DOM existe antes de crear un nuevo 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
fuente
1
Pero todo lo que hace es detener el mapa que se está creando, en realidad no arreglar el desastre y crear el mapa.
Ryan The Leach
1

Si usa formularios web asp.net y está registrando el script en el código detrás de una página usando una página maestra, no olvide usar el ID de cliente del elemento de mapa (vb.net):

ClientScript.RegisterStartupScript(Me.[GetType](), "Google Maps Initialization", String.Format("init_map(""" & map_canvas.ClientID() & """...
Guiños
fuente
1

Para resolverlo, debe agregar async deferal script.

Debería ser así:

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

Vea aquí el significado de aplazamiento asíncrono.

Dado que invocará una función desde el archivo js principal, también debe asegurarse de que sea posterior a la que carga el script principal.

Avi Levin
fuente
1

Asegúrese de incluir el &libraries=placesparámetro de la biblioteca de Lugares cuando cargue la API por primera vez.

Por ejemplo:

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

Sé que llego un poco tarde a la fiesta, solo quería agregar que el error también puede ocurrir cuando el div no existe en la página. También puede verificar si el div existe primero antes de cargar la llamada a la función 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
fuente
1
  • Configura ng-init = init () en tu HTML
  • Y en el controlador

    use $ scope.init = function () {...} en lugar de google.maps.event.addDomListener (window, "load", init) {...}

Espero que esto te ayudará.

Akash Saxena
fuente
0

En realidad, la forma más fácil de solucionar esto es simplemente mover su objeto antes de que el código Javascript me funcione. Supongo que en su respuesta el objeto se carga después del 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
fuente
0

Comprueba que no estás anulando window.self

Mi problema: había creado un componente y escribí en self = thislugar de var self = this. Si no usa la palabra clave var, JS colocará esa variable en el objeto de la ventana, por lo que sobrescribí lo window.selfque causó este error.

Mike R Emo
fuente
0

Esta es una edición de una publicación eliminada previamente para contener el contenido de la respuesta vinculada, en la propia respuesta. El propósito de volver a publicar esta respuesta es funcionar como un PSA para los usuarios de React 0.9+ que también se han topado con este problema.

publicación original editada


También recibí este error al usar ReactJS mientras seguía esta publicación de blog . comentario de sahat aquí ayudó: vea el contenido del comentario de sahat a continuación.

❗️ Nota para reaccionar> = 0.9

Antes de v0.9, el nodo DOM se pasaba como el último argumento. Si estaba usando esto, aún puede acceder al nodo DOM llamando a this.getDOMNode ().

En otras palabras, reemplace el parámetro rootNode con this.getDOMNode () en la última versión de React.

Meredith
fuente
0

Mi falla fue usar

zoomLevel

como una opción, en lugar de la opción correcta

zoom
Strattonn
fuente
0

agregue aplazamiento asíncrono al comienzo de la llamada de la clave de API del mapa.

Ghadir Farzaneh
fuente
0

En un caso con el que estaba lidiando, el mapa div se renderizó condicionalmente dependiendo de si la ubicación se hacía pública. Si no puede estar seguro de si el div de lienzo del mapa estará en la página, simplemente verifique que document.getElementByIddevuelva un elemento e invoque el mapa solo si está presente:

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

Aquí el problema era el enlace API sin el keyparámetro:

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

De esa manera funciona bien.

vaati
fuente