API Google MAP Uncaught TypeError: Неможливо прочитати властивість 'offsetWidth' null


204

Я намагаюся використовувати API Google MAP v3 із наступним кодом.

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

Коли я запускаю цей код, браузер говорить це.

Uncaught TypeError: Неможливо прочитати властивість 'offsetWidth' null

Я поняття не маю, оскільки дотримуюся вказівки, наведеної в цьому підручнику .

У вас є якісь підказки?

Відповіді:


317

Ця проблема, як правило, пов’язана з тим, що div-карта не виводиться до запуску javascript, який потребує доступу до нього.

Ви повинні поставити код ініціалізації всередині функції завантаження або внизу вашого HTML-файлу, безпосередньо перед тегом, щоб DOM був повністю виведений перед його виконанням (зауважте, що другий варіант більш чутливий до недійсного HTML).

Зауважте, як вказували matthewsheets, це також може бути причиною від div з цим ідентифікатором, який взагалі не існує у вашому HTML (патологічний випадок, коли div не виводиться)

Додавання зразка коду з публікації wf9a5m75 , щоб розмістити все в одному місці:

<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
Це трапляється зі мною весь час, коли я забуваю обумовити сценарій своїх карт. Додавання: var mapExists = document.getElementById ("карта-полотно"); якщо (mapExists) {// script} робить це все краще.
імператив

109

Для інших, у яких може виникнути ця проблема , навіть після спроби вищезазначених рекомендацій використання неправильного селектора полотна вашої картки у функції ініціалізації може спричинити цю проблему, оскільки функція намагається отримати доступ до чогось неіснуючого. Двічі перевірте, чи відповідає ваша карта Id у вашій функції ініціалізації, і ваш HTML чи та сама помилка може бути викинута.

Іншими словами, переконайтеся, що ваші посвідчення особи збігаються. ;)


3
Дивно, як ти можеш бути таким впевненим, що це не проблема… поки ти ще раз не перевіриш і не зрозумієш, що ти змінив її раніше тестування і забув змінити її назад. :-)
Чарлі Горічаназ

28

Ви також можете отримати цю помилку, якщо не вказали centerабо не вказали zoomпараметри вашої карти.


2
Це був один! Видалено масштаб з параметрів, оскільки я все-таки встановив його пізніше в сценарії, і бум, карта завантажиться в перший раз, але вдруге призведе до цієї помилки. Дякую!!
Ієн Грант

Так, це було моє! Мав масштаб, але немає центру. Просто додавання центру виправлено.
Whelkaholism

1
Вони хоча б могли записати якесь повідомлення в консолі, принаймні, справді. Дякую!
Мартін Шишков

26

google використовує id="map_canvas"та id="map-canvas"у зразках двічі перевірте та повторно перевірте id: D


23

Рік, відповідь геокодезипа правильна. Тож змініть свій код так: (якщо у вас все ще виникають проблеми, чи, можливо, хтось ще в майбутньому)

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

Точно спочатку візуалізуйте html div, а потім JS ще додайте слухача подій.
foxybagga

11

Просто я додаю свій невдалий сценарій, щоб дозволити цьому працювати. У мене було місце, <div id="map>в якому я завантажував карту:

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

і div спочатку був прихованим, і він не мав явно встановлених значень ширини та висоти, тому його розмір був width x 0. Одного разу я встановив розмір цього діва в CSS, як цей

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

все працювало! Сподіваюся, що це комусь допоможе.


Це була саме причина, чому це не працювало для мене. Потрібно переконатися, що CSS відповідає вашому ідентифікатору карти, і що у вас є якесь початкове комбіноване ширину / висоту, інакше нічого не буде показано. Отже, підберіть підсумок: 1. переконайтеся, що ваш HTML-код id відповідає селектору ідентифікатора, коли ви викликаєте getElementById у своєму JavaScript 2. переконайтесь, що CSS має код для стилювання вашої конкретної карти, наприклад, # map1 {width: 200px; висота: 200px; } або подібне, щоб воно відображалось.
Тахір Халід

7

Для ще більшої кількості інших, у яких може виникнути ця проблема, я використовував <div id="map1" />тег, що самозамикається , а другий div не показував і, схоже, не знаходився у домі. як тільки я змінив його на два теги відкритого та закритого, <div id="map1"></div>він працював. чт


6

Також подбайте про те, щоб не писати

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

правильно:

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

Справді. Це була проблема і в моєму випадку. Перший запускає функцію init відразу, коли другий просто передає функцію init як параметр слухачеві подій, який запускатиме функцію init, коли ця подія відбувається. stackoverflow.com/questions/13286233 / ...
kivikall

6

У мене були одиничні цитати в своїх

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

і замінив їх подвійними цитатами

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

Це зробило для мене трюк.


5

Змінення ідентифікатора (у всіх 3 місцях) з "map-canvas" на "map" виправило його для мене, навіть якщо я переконався, що ідентифікатори однакові, div має ширину та висоту, а код не був працює до завершення виклику завантаження вікна. Це не тире; Схоже, це не працює з іншим ідентифікатором, ніж "карта".


4

Також переконайтеся, що ви не розміщуєте хеш-символ (#) всередині вашого селектора в

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

    document.getElementById('map') // good

заява. Це не jQuery. Просто швидке нагадування для когось, хто поспішає.


3

У мене була така ж проблема, але проблема полягала в тому, що масштаб не був визначений в межах об'єкта параметрів, наданих Карту Google.


2

Якщо ви створюєте декілька карт у циклі, якщо одного елемента DOM на карті не існує, він розбиває їх усі. Спочатку перевірте, чи переконайтеся, що елемент DOM існує, перш ніж створити новий об’єкт 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
Але все, що потрібно зробити - це зупинити створення карти, а не насправді виправити безлад і створити карту.
Райан Ліч

1

Якщо ви користуєтеся веб-формами asp.net і реєструєте скрипт у коді позаду сторінки за допомогою головної сторінки, не забудьте скористатися clientID елемента елемента (vb.net):

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

1

Для того, щоб вирішити це, вам потрібно додати async deferдо сценарію.

Він повинен бути таким:

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

Дивіться тут значення асинхронного відкладання.

Оскільки ви будете викликати функцію з головного js-файлу, ви також хочете переконатися, що це після того, де ви завантажуєте основний скрипт.


1

Переконайтеся, що ви включили &libraries=placesпараметр бібліотеки місць при першому завантаженні API.

Наприклад:

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

1

Я знаю, що я трохи спізнився на вечірку, просто хотів додати, що помилка може трапитися і тоді, коли div не існує на сторінці. Ви також можете перевірити, чи існує div першим, перш ніж завантажувати виклик функції Google Maps. Щось на зразок

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
  • Установіть ng-init = init () у своєму HTML
  • І в контролері

    використовуйте $ range.init = function () {...} замість google.maps.event.addDomListener (вікно, "завантажувати", init) {...}

Сподіваюся, що це вам допоможе.


0

Насправді найпростіший спосіб виправити це - просто перемістити об’єкт перед тим, як Javascript-код працював на мене. Я здогадуюсь, ваш об’єкт відповідей завантажується після коду 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

Переконайтеся, що ви не переосмислюєте window.self

Моє питання: Я створив компонент і написав self = thisзамість var self = this. Якщо ви не використовуєте ключове слово var, JS помістить цю змінну на об’єкт вікна, тому я перезаписав, window.selfщо спричинило цю помилку.


0

Це редагування раніше видаленої публікації, що містить вміст пов'язаної відповіді, у самій відповіді. Метою повторної публікації цієї відповіді є функціонування PSA для користувачів React 0.9+, які також натрапили на цю проблему.

оригінальний відредагований пост


Також виникла ця помилка під час використання ReactJS під час виконання цього повідомлення в блозі . коментар sahat тут допоміг - дивіться зміст коментаря sahat нижче.

❗️ Примітка для Реакції> = 0,9

До версії v0.9 вузол DOM був переданий як останній аргумент. Якщо ви використовували це, ви все одно можете отримати доступ до вузла DOM, зателефонувавши до цього.getDOMNode ().

Іншими словами, замініть параметр rootNode на this.getDOMNode () в останній версії React.


0

Моя невдача полягала у використанні

zoomLevel

як варіант, а не правильний варіант

zoom

0

додати відкладати асинхрон на початку виклику ключа api на карті.


0

У випадку, з яким я маю справу, діл карти було умовно винесено залежно від того, чи було оприлюднено місце розташування. Якщо ви не можете бути впевнені, чи на сторінці буде розміщена картина полотна карти, просто перевірте, document.getElementByIdчи повертається елемент, і викликте лише карту, якщо вона присутня:

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

-2

Тут проблема полягала в посиланні API без keyпарам:

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

Це добре працює.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.