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?

jaeyong
źródło

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>
geocodezip
źródło
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. ;)

Arkusze Mateusza
źródło
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.

JamesFrost
źródło
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

dpineda
źródło
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>
wf9a5m75
źródło
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.

Nikola
źródło
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

changokun
źródło
6

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

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

poprawny:

google.maps.event.addDomListener(window, "load", init)
Mikrofon
źródło
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ę.

Programator VB.Net
źródło
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”.

Johnny5k
źródło
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.

Keeprock
źródło
3

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

torresomar
źródło
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);
}

[...]
Zack Katz
źródło
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() & """...
Mruga
źródło
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.

Avi Levin
źródło
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">
Steve
źródło
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
     }
}
mr_j
źródło
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.

Akash Saxena
źródło
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>
Laltzi
źródło
0

W moim przypadku tego rodzaju problemy zostały rozwiązane za pomocą defer https://developer.mozilla.org/en/docs/Web/HTML/Element/script

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

Musisz jednak wziąć pod uwagę obsługę tej opcji przez przeglądarki (nie widziałem problemów)

Yercalamarino
źródło
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.

Mike R Emo
źródło
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.

Meredith
źródło
0

Moja porażka polegała na użyciu

zoomLevel

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

zoom
strattonn
źródło
0

dodaj odłożenie asynchroniczne na początku wywołania klawisza interfejsu API mapy.

Ghadir Farzaneh
źródło
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);
}
Rillus
źródło
-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.

Vaati
źródło