API MAP di Google non rilevata TypeError: impossibile leggere la proprietà 'offsetWidth' di null


204

Sto cercando di utilizzare Google MAP API v3 con il seguente codice.

<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 eseguo questo codice, il browser dice questo.

TypeError non rilevato: impossibile leggere la proprietà 'offsetWidth' di null

Non ne ho idea, poiché seguo la direzione fornita in questo tutorial .

Hai qualche idea?

Risposte:


317

Questo problema è di solito dovuto al fatto che il div della mappa non viene riprodotto prima dell'esecuzione di javascript che deve accedervi.

Dovresti inserire il codice di inizializzazione all'interno di una funzione di caricamento o nella parte inferiore del file HTML, appena prima del tag, in modo che il DOM sia completamente renderizzato prima di essere eseguito (nota che la seconda opzione è più sensibile all'HTML non valido).

Nota, come sottolineato da matthewsheets, anche questo potrebbe essere causato dal div con quell'id che non esiste affatto nel tuo HTML (il caso patologico del div che non viene visualizzato)

Aggiunta di esempio di codice dal post di wf9a5m75 per mettere tutto in un posto:

<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
Questo succede a me tutto il tempo quando dimentico di condizionare il mio script di mappe. Aggiunta: var mapExists = document.getElementById ("map-canvas"); if (mapExists) {// script} rende tutto migliore.
Imperativo

109

Per altri che potrebbero ancora avere questo problema , anche dopo aver provato i consigli di cui sopra, l'uso di un selettore errato per il canvas della mappa nella funzione di inizializzazione può causare lo stesso problema in quanto la funzione sta tentando di accedere a qualcosa che non esiste. Controlla che l'ID della tua mappa corrisponda alla tua funzione di inizializzazione e che il tuo HTML o questo stesso errore possano essere generati.

In altre parole, assicurati che i tuoi ID coincidano. ;)


3
Incredibile come puoi essere così sicuro che questo non sia il problema ... fino a quando non ricontrollerai e ti renderai conto di averlo cambiato prima dei test e di aver dimenticato di cambiarlo di nuovo. :-)
Charlie Gorichanaz,

28

Puoi anche ottenere questo errore se non specifichi centero zoomnelle opzioni della tua mappa.


2
Quello era quello! Rimosso lo zoom dalle opzioni da quando lo stavo impostando in seguito nello script comunque, e boom, la mappa si sarebbe caricata la prima volta, ma la seconda volta avrebbe generato quell'errore. Grazie!!
Iain Grant

Sì, questo era mio! Aveva uno zoom ma nessun centro. Basta aggiungere il centro risolto.
Whelkaholism

1
Potrebbero aver registrato almeno qualche messaggio nella console, davvero. Grazie!
Martin Shishkov,

26

google utilizza id="map_canvas"e id="map-canvas"negli esempi ricontrolla e ricontrolla l'id: D


23

Anno, la risposta di geocodezip è corretta. Quindi cambia il codice in questo modo: (se sei ancora nei guai, o forse qualcun altro in 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>

Esatto, prima esegui il rendering del div html e poi JS altrimenti aggiunge un listener di eventi.
Foxybagga,

11

Solo così aggiungo il mio scenario di fallimento nel farlo funzionare. Ho avuto un <div id="map>in cui stavo caricando la mappa con:

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

e il div era inizialmente nascosto e non aveva esplicitamente impostato valori di larghezza e altezza, quindi la sua dimensione era width x 0. Una volta ho impostato le dimensioni di questo div in CSS in questo modo

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

tutto ha funzionato! Spero che questo aiuti qualcuno.


Questo era esattamente il motivo per cui non ha funzionato per me. Devi assicurarti che il CSS corrisponda al tuo id della mappa e che tu abbia una sorta di combo larghezza / altezza iniziale, altrimenti non viene visualizzato nulla. Quindi, per ricapitolare: 1. assicurati che il tuo ID div html corrisponda al selettore id quando chiami getElementById nel tuo JavaScript 2. assicurati che il CSS abbia un codice per modellare la tua mappa particolare, ad esempio # map1 {larghezza: 200px; altezza: 200 px; } o simile in modo da renderlo.
Tahir Khalid,

7

Per altri ancora che potrebbero ancora avere questo problema, stavo usando un <div id="map1" />tag a chiusura automatica , e il secondo div non stava mostrando e non sembrava essere nel dom. non appena l'ho cambiato in due tag di apertura e chiusura <div id="map1"></div>ha funzionato. hth


6

Fai anche attenzione a non scrivere

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

corretta:

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

Infatti. Anche questo è stato un problema nel mio caso. Il primo esegue immediatamente la funzione init quando il secondo passa la funzione init come parametro al listener di eventi che eseguirà la funzione init quando si verifica quell'evento. stackoverflow.com/questions/13286233/...
kivikall

6

Ho avuto virgolette singole nel mio

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

e li ha sostituiti con virgolette doppie

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

Questo ha fatto il trucco per me.


5

La modifica dell'ID (in tutti e 3 i punti) da "map-canvas" a "map" lo ha riparato per me, anche se mi ero assicurato che gli ID fossero gli stessi, il div aveva una larghezza e un'altezza e il codice non lo era in esecuzione fino a dopo la chiamata di caricamento della finestra. Non è il trattino; non sembra funzionare con nessun altro ID diverso da "map".


4

Inoltre, assicurati di non posizionare il simbolo hash (#) all'interno del selettore in a

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

    document.getElementById('map') // good

dichiarazione. Non è un jQuery. Solo un rapido promemoria per qualcuno che ha fretta.


3

Ho avuto lo stesso problema ma il problema era che lo zoom non era definito nell'oggetto opzioni fornito a Google Maps.


2

Se stai creando più mappe in un ciclo, se non esiste un singolo elemento DOM della mappa, le interrompe tutte. Innanzitutto, verifica che l'elemento DOM esista prima di creare un nuovo oggetto Mappa.

[...]

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
Ma tutto ciò che fa è interrompere la creazione della mappa, in realtà non risolve il pasticcio e crea la mappa.
Ryan The Leach,

1

Se stai usando asp.net Webforms e stai registrando lo script nel codice dietro una pagina usando una pagina master, non dimenticare di usare il clientID dell'elemento map (vb.net):

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

1

Per risolverlo è necessario aggiungere async deferallo script.

Dovrebbe essere così:

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

Vedi qui il significato di differito asincrono.

Dal momento che chiamerai una funzione dal file js principale, vuoi anche assicurarti che questo sia dopo quello in cui carichi lo script principale.


1

Assicurati di includere la libreria Luoghi &libraries=places parametro della al primo caricamento dell'API.

Per esempio:

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

1

So di essere un po 'in ritardo alla festa, volevo solo aggiungere che l'errore può verificarsi anche quando il div non esiste nella pagina. Puoi anche verificare se il div esiste prima di caricare la chiamata della funzione google maps. Qualcosa di simile a

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
  • Imposta ng-init = init () nel tuo HTML
  • E nel controller

    usa $ scope.init = function () {...} invece di google.maps.event.addDomListener (window, "load", init) {...}

Spero che questo ti possa aiutare.


0

Il modo più semplice per risolvere questo problema è semplicemente spostare l'oggetto prima che il codice Javascript funzioni. Immagino che il tuo oggetto risposta sia caricato dopo il codice 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

Controlla che non stai ignorando window.self

Il mio problema: avevo creato un componente e scritto self = thisinvece di var self = this. Se non usi la parola chiave var, JS inserirà quella variabile nell'oggetto finestra, quindi ho sovrascritto ciò window.selfche ha causato questo errore.


0

Questa è una modifica di un post precedentemente eliminato per contenere il contenuto della risposta collegata, nella risposta stessa. Lo scopo di ripubblicare questa risposta è di fungere da PSA per gli utenti di React 0.9+ che si sono anche imbattuti in questo problema.

post originale modificato


Ho anche ottenuto questo errore durante l'utilizzo di ReactJS mentre seguivo questo post del blog . Il commento di sahat qui è stato di aiuto: vedere di seguito il contenuto del commento di sahat.

❗️ Nota per React> = 0.9

Prima della v0.9, il nodo DOM era passato come ultimo argomento. Se lo stavi usando, puoi comunque accedere al nodo DOM chiamando this.getDOMNode ().

In altre parole, sostituisci il parametro rootNode con this.getDOMNode () nell'ultima versione di React.


0

Il mio fallimento è stato quello di usare

zoomLevel

come opzione, piuttosto che l'opzione corretta

zoom

0

aggiungere il differimento asincrono all'inizio della chiamata del tasto API della mappa.


0

In un caso di cui mi occupavo, il div della mappa veniva reso condizionatamente a seconda che la posizione fosse resa pubblica. Se non sei sicuro che il div della mappa della mappa sia sulla pagina, controlla semplicemente che stai document.getElementByIdrestituendo un elemento e invoca la mappa solo se è presente:

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

-2

Qui il problema era il collegamento API senza il keyparametro:

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

In questo modo funziona bene.

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.