Google MAP API Uncaught TypeError: Nie można odczytać właściwości „offsetWidth” o wartości null


204

Próbuję użyć Google MAP API v3 z następującym kodem.

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

Kiedy uruchamiam ten kod, przeglądarka to mówi.

Uncaught TypeError: Nie można odczytać właściwości „offsetWidth” o wartości null

Nie mam pojęcia, ponieważ kieruję się wskazówkami podanymi w tym samouczku .

Czy masz jakieś wskazówki?

Odpowiedzi:


317

Ten problem jest zwykle spowodowany tym, że div mapy nie jest renderowany przed uruchomieniem javascript, który musi uzyskać do niego dostęp.

Powinieneś umieścić kod inicjujący w funkcji onload lub na dole pliku HTML, tuż przed znacznikiem, aby DOM był całkowicie renderowany przed jego wykonaniem (zwróć uwagę, że druga opcja jest bardziej wrażliwa na niepoprawny HTML).

Zauważ, jak zauważyli Matthewsheets, może to być również spowodowane przez div z tym identyfikatorem w ogóle nieistniejącym w twoim HTML (patologiczny przypadek div nie jest renderowany)

Dodanie próbki kodu z postu wf9a5m75 w celu umieszczenia wszystkiego w jednym miejscu:

<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
Zdarza mi się to cały czas, gdy zapominam o warunkowaniu skryptu map. Dodanie: var mapExists = document.getElementById („map-canvas”); if (mapExists) {// script} sprawia, że ​​wszystko jest lepsze.
Imperative

109

W przypadku innych, którzy mogą nadal występować ten problem , nawet po wypróbowaniu powyższych zaleceń, użycie niepoprawnego selektora dla obszaru roboczego mapy w funkcji inicjalizacji może spowodować ten sam problem, ponieważ funkcja próbuje uzyskać dostęp do czegoś, co nie istnieje. Sprawdź dokładnie, czy identyfikator mapy pasuje do funkcji inicjalizacji, a kod HTML lub ten sam błąd może zostać zgłoszony.

Innymi słowy, upewnij się, że Twoje identyfikatory są zgodne. ;)


3
Niesamowite, jak możesz być pewien, że to nie jest problem… dopóki nie sprawdzisz dwukrotnie i nie zauważysz, że zmieniłeś go wcześniej, i nie zapomniałeś go zmienić. :-)
Charlie Gorichanaz

28

Ten błąd można również uzyskać, jeśli nie zostanie określony centerlub zoomw opcjach mapy.


2
To był ten! Usunąłem zoom z opcji, ponieważ i tak ustawiałem go później w skrypcie, i bum, mapa załaduje się za pierwszym razem, ale za drugim razem wygeneruje ten błąd. Dziękuję Ci!!
Iain Grant

Tak, to było moje! Miałem zoom, ale nie centrum. Właśnie dodanie centrum naprawiło to.
Whelkaholism

1
Naprawdę mogli zarejestrować jakąś wiadomość w konsoli. Dzięki!
Martin Shishkov

26

Google używa id="map_canvas"iw id="map-canvas"przykładach dwukrotnie sprawdź i ponownie sprawdź identyfikator: D


23

Rok, odpowiedź geocodezip jest poprawna. Więc zmień kod w ten sposób: (jeśli nadal masz kłopoty, a może ktoś w przyszłości)

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

Dokładnie, najpierw wyrenderuj html div, a następnie JS dodaj detektor zdarzeń.
foxybagga

11

Właśnie dlatego dodaję mój scenariusz niepowodzenia, aby to zadziałało. Miałem taki, <div id="map>w którym ładowałem mapę:

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

div był początkowo ukryty i nie miał wyraźnie ustawionych wartości szerokości i wysokości, więc jego rozmiar był width x 0. Kiedyś ustawiłem rozmiar tego div w CSS w ten sposób

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

wszystko działało! Mam nadzieję, że to komuś pomoże.


To był dokładnie powód, dla którego to nie działało dla mnie. Musisz upewnić się, że CSS pasuje do twojego identyfikatora mapy i że masz jakąś kombinację początkowej szerokości / wysokości, w przeciwnym razie nic nie będzie renderowane. Podsumowując: 1. upewnij się, że identyfikator div html pasuje do selektora id, gdy wywołujesz getElementById w swoim JavaScript 2. upewnij się, że CSS ma kod do stylizowania twojej konkretnej mapy, np. # Map1 {width: 200px; wysokość: 200 pikseli; } lub podobny, więc renderuje.
Tahir Khalid

7

Dla jeszcze większej liczby innych osób, które wciąż mogą mieć ten problem, użyłem <div id="map1" />tagu samozamykającego , a drugi div nie wyświetlał się i nie wyglądał, jakby był w domenie. jak tylko zmieniłem go na dwa tagi „otwórz i zamknij” <div id="map1"></div>, zadziałało. hth


6

Uważaj również, aby nie pisać

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

poprawny:

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

W rzeczy samej. To też był problem w moim przypadku. Pierwszy uruchamia funkcję init od razu, gdy drugi przekazuje funkcję init jako parametr do nasłuchiwania zdarzeń, który uruchomi funkcję init, kiedy to zdarzenie nastąpi. stackoverflow.com/questions/13286233/…
kivikall,

6

Miałem w sobie pojedyncze cytaty

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

i zastąpiłem je podwójnymi cudzysłowami

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

To załatwiło sprawę.


5

Zmiana identyfikatora (we wszystkich 3 miejscach) z „map-canvas” na „map” naprawiła go, mimo że upewniłem się, że identyfikatory są takie same, div ma szerokość i wysokość, a kod nie jest działający do czasu po wczytaniu okna. To nie jest kreska; wydaje się, że nie działa z żadnym innym identyfikatorem niż „mapa”.


4

Upewnij się również, że nie umieszczasz symbolu skrótu (#) wewnątrz selektora w

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

    document.getElementById('map') // good

komunikat. To nie jest jQuery. Szybkie przypomnienie dla kogoś, kto się spieszy.


3

Miałem ten sam problem, ale problem polegał na tym, że powiększenie nie zostało zdefiniowane w obiekcie opcji przekazanym Mapom Google.


2

Jeśli tworzysz wiele map w pętli, jeśli pojedynczy element DOM mapy nie istnieje, powoduje to uszkodzenie wszystkich z nich. Najpierw sprawdź, czy element DOM istnieje, zanim utworzysz nowy obiekt 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
Ale to wszystko powstrzymuje tworzenie mapy, a nie naprawia bałagan i tworzenie mapy.
Ryan The Leach

1

Jeśli używasz formularzy internetowych asp.net i rejestrujesz skrypt w kodzie strony za pomocą strony wzorcowej, nie zapomnij użyć identyfikatora klienta elementu mapy (vb.net):

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

1

Aby go rozwiązać, musisz dodać async deferdo skryptu.

Powinno to wyglądać tak:

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

Zobacz tutaj znaczenie async defer.

Ponieważ będziesz wywoływał funkcję z głównego pliku js, musisz także upewnić się, że jest ona następująca po tym, w którym ładujesz główny skrypt.


1

Upewnij się, że dołączasz &libraries=placesparametr biblioteki miejsc podczas pierwszego ładowania interfejsu API.

Na przykład:

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

1

Wiem, że jestem trochę spóźniony na imprezę, chciałem tylko dodać, że błąd może również wystąpić, gdy div nie istnieje na stronie. Możesz także sprawdzić, czy div istnieje najpierw przed załadowaniem wywołania funkcji Google Maps. Coś jak

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
  • Skonfiguruj ng-init = init () w swoim HTML
  • I w kontrolerze

    użyj $ scope.init = function () {...} zamiast google.maps.event.addDomListener (okno, „load”, init) {...}

Mam nadzieję, że to ci pomoże.


0

Naprawdę najłatwiejszym sposobem na rozwiązanie tego problemu jest po prostu przeniesienie obiektu, zanim kod JavaScript zadziałał. Chyba w twojej odpowiedzi obiekt jest ładowany po kodzie 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

Sprawdź, czy nie zastępujesz window.self

Mój problem: stworzyłem komponent i napisałem self = thiszamiast var self = this. Jeśli nie użyjesz słowa kluczowego var, JS umieści tę zmienną na obiekcie okna, więc nadpisałem, window.selfco spowodowało ten błąd.


0

To jest edycja wcześniej usuniętego postu, która zawiera treść połączonej odpowiedzi w samej odpowiedzi. Celem ponownego opublikowania tej odpowiedzi jest funkcjonowanie jako PSA dla użytkowników React 0.9+, którzy również natknęli się na ten problem.

oryginalny edytowany post


Ten błąd również wystąpił podczas korzystania z ReactJS podczas śledzenia tego postu na blogu . Komentarz sahat tutaj pomógł - zobacz treść komentarza sahat poniżej.

❗️ Uwaga dla React> = 0,9

Przed wersją 0.9 węzeł DOM był przekazywany jako ostatni argument. Jeśli tego używasz, nadal możesz uzyskać dostęp do węzła DOM, wywołując this.getDOMNode ().

Innymi słowy, zamień parametr rootNode na this.getDOMNode () w najnowszej wersji React.


0

Moja porażka polegała na użyciu

zoomLevel

jako opcję, a nie właściwą opcję

zoom


0

W przypadku, z którym miałem do czynienia, div mapy został warunkowo renderowany w zależności od tego, czy lokalizacja została podana do wiadomości publicznej. Jeśli nie masz pewności, czy div płótna mapy będzie na stronie, po prostu sprawdź, czy document.getElementByIdzwraca element, i wywołaj mapę tylko wtedy, gdy jest obecna:

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

-2

Tutaj problemem był link API bez keyparametrów:

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

W ten sposób działa dobrze.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.