Google MAP API Uncaught TypeError: Không thể đọc thuộc tính 'offsetWidth' của null


204

Tôi đang cố gắng sử dụng Google MAP API v3 với mã sau đây.

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

Khi tôi chạy mã này, trình duyệt nói điều này.

Uncaught TypeError: Không thể đọc thuộc tính 'offsetWidth' của null

Tôi không có ý tưởng, vì tôi làm theo hướng dẫn trong hướng dẫn này .

Bạn có chút manh mối nào không?

Câu trả lời:


317

Vấn đề này thường là do div bản đồ không được hiển thị trước khi javascript chạy cần truy cập.

Bạn nên đặt mã khởi tạo của mình bên trong hàm onload hoặc ở dưới cùng của tệp HTML, ngay trước thẻ, để DOM được hiển thị hoàn toàn trước khi thực thi (lưu ý rằng tùy chọn thứ hai nhạy hơn với HTML không hợp lệ).

Lưu ý, như được chỉ ra bởi matthewsheet, điều này cũng có thể là do div có id đó hoàn toàn không tồn tại trong HTML của bạn (trường hợp bệnh lý của div không được hiển thị)

Thêm mẫu mã từ bài đăng của wf9a5m75 để đặt mọi thứ ở một nơi:

<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
Điều này xảy ra với tôi mọi lúc khi tôi quên điều kiện hóa kịch bản bản đồ của mình. Thêm: var mapExists = document.getEuityById ("map-canvas"); if (mapExists) {// script} làm cho tất cả tốt hơn.
Bắt buộc

109

Đối với những người khác vẫn có thể gặp phải sự cố này , ngay cả sau khi thử các đề xuất ở trên, sử dụng bộ chọn không chính xác cho khung vẽ bản đồ của bạn trong chức năng khởi tạo có thể gây ra vấn đề tương tự vì chức năng này đang cố truy cập vào thứ không tồn tại. Kiểm tra kỹ xem Id bản đồ của bạn có khớp với chức năng khởi tạo của bạn không và HTML của bạn hoặc lỗi tương tự này có thể bị ném.

Nói cách khác, đảm bảo ID của bạn trùng khớp. ;)


3
Thật ngạc nhiên khi bạn có thể chắc chắn rằng đây không phải là vấn đề mà cho đến khi bạn kiểm tra lại và nhận ra rằng bạn đã thay đổi thử nghiệm trước đó và quên thay đổi lại. :-)
Charlie Gorichanaz

28

Bạn cũng có thể gặp lỗi này nếu bạn không chỉ định centerhoặc zoomtrong các tùy chọn bản đồ của mình.


2
Đó là một trong những! Đã xóa thu phóng khỏi các tùy chọn vì dù sao tôi cũng cài đặt nó trong tập lệnh và bùng nổ, bản đồ sẽ tải lần đầu tiên, nhưng lần thứ hai sẽ tạo ra lỗi đó. Cảm ơn bạn!!
Iain Grant

Yup, đây là của tôi! Có zoom nhưng không có trung tâm. Chỉ cần thêm trung tâm cố định nó.
Chủ nghĩa cá nhân

1
Họ đã có thể đăng nhập một số tin nhắn trong bảng điều khiển ít nhất, thực sự. Cảm ơn!
Martin Shishkov

26

google sử dụng id="map_canvas"id="map-canvas"trong các mẫu, kiểm tra lại và kiểm tra lại id: D


23

Năm, câu trả lời của geocodezip là chính xác. Vì vậy, thay đổi mã của bạn như thế này: (nếu bạn vẫn gặp rắc rối, hoặc có thể ai đó khác trong tương lai)

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

Chính xác, đầu tiên kết xuất div html và sau đó, JS khác thêm một trình lắng nghe sự kiện.
foxybagga

11

Chỉ để tôi thêm kịch bản thất bại của tôi trong việc này để làm việc. Tôi đã có một <div id="map>trong đó tôi đang tải bản đồ với:

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

và div ban đầu bị ẩn và nó không có giá trị chiều rộng và chiều cao được đặt rõ ràng nên kích thước của nó là width x 0. Khi tôi đã đặt kích thước của div này trong CSS như thế này

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

mọi thứ đã làm việc Hy vọng điều này sẽ giúp được ai đó.


Đây chính xác là lý do tại sao nó không làm việc cho tôi. Bạn cần đảm bảo CSS khớp với id bản đồ của bạn và bạn có một số loại kết hợp chiều rộng / chiều cao ban đầu nếu không sẽ không có gì được hiển thị. Vì vậy, để tóm tắt lại: 1. đảm bảo id div html của bạn khớp với bộ chọn id khi bạn gọi getEuityById trong JavaScript của mình 2. đảm bảo CSS có mã để định kiểu bản đồ cụ thể của bạn, ví dụ # map1 {width: 200px; chiều cao: 200px; } hoặc tương tự để nó ám.
Tahir Khalid

7

Đối với nhiều người khác vẫn có thể gặp phải vấn đề này, tôi đã sử dụng thẻ tự đóng <div id="map1" />và div thứ hai không hiển thị và dường như không có trong dom. ngay sau khi tôi thay đổi nó thành hai thẻ mở và đóng, <div id="map1"></div>nó đã hoạt động. thứ


6

Cũng cẩn thận không viết

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

chính xác:

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

Thật. Đó cũng là một vấn đề trong trường hợp của tôi. Hàm thứ nhất chạy ngay hàm init khi hàm thứ hai chỉ truyền hàm init dưới dạng tham số cho trình nghe sự kiện sẽ chạy hàm init khi sự kiện đó xảy ra. stackoverflow.com/questions/13286233/
hy

6

Tôi đã có dấu ngoặc đơn trong

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

và thay thế chúng bằng dấu ngoặc kép

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

Điều này đã lừa tôi.


5

Việc thay đổi ID (ở cả 3 vị trí) từ "map-canvas" thành "map" đã sửa nó cho tôi, mặc dù tôi đã chắc chắn rằng ID giống nhau, div có chiều rộng và chiều cao và mã không chạy cho đến sau cuộc gọi tải cửa sổ. Đó không phải là dấu gạch ngang; nó dường như không hoạt động với bất kỳ ID nào khác ngoài "bản đồ".


4

Ngoài ra, hãy đảm bảo bạn không đặt biểu tượng băm (#) bên trong bộ chọn của mình trong

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

    document.getElementById('map') // good

tuyên bố. Nó không phải là một jQuery. Chỉ là một lời nhắc nhở nhanh chóng cho một người vội vàng.


3

Tôi có cùng một vấn đề nhưng vấn đề là thu phóng không được xác định trong đối tượng tùy chọn được cung cấp cho Google Maps.


2

Nếu bạn đang tạo nhiều bản đồ trong một vòng lặp, nếu một phần tử DOM bản đồ duy nhất không tồn tại, nó sẽ phá vỡ tất cả chúng. Trước tiên, hãy kiểm tra để đảm bảo phần tử DOM tồn tại trước khi tạo đối tượng Bản đồ mới.

[...]

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
Nhưng tất cả những gì làm là ngăn bản đồ được tạo ra, không thực sự sửa chữa mớ hỗn độn và tạo bản đồ.
Ryan The Leach

1

Nếu bạn tình cờ sử dụng các biểu mẫu web asp.net và đang đăng ký tập lệnh ở mã phía sau trang bằng trang chính, đừng quên sử dụng clientID của thành phần bản đồ (vb.net):

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

1

Để giải quyết nó, bạn cần thêm async defervào kịch bản.

Nó nên như thế này:

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

Xem ở đây ý nghĩa của trì hoãn async.

Vì bạn sẽ gọi một hàm từ tệp js chính, nên bạn cũng muốn đảm bảo rằng đây là hàm sau khi bạn tải tập lệnh chính.


1

Đảm bảo bạn bao gồm &libraries=placestham số thư viện Địa điểm khi bạn tải API lần đầu tiên.

Ví dụ:

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

1

Tôi biết tôi đến bữa tiệc muộn một chút, chỉ muốn thêm rằng lỗi cũng có thể xảy ra khi div không tồn tại trong trang. Bạn cũng có thể kiểm tra xem div có tồn tại trước khi tải lệnh gọi chức năng google maps không. Cái gì đó như

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
  • Thiết lập ng-init = init () trong HTML của bạn
  • Và trong bộ điều khiển

    sử dụng $ scope.init = function () {...} thay vì google.maps.event.addDomListener (cửa sổ, "load", init) {...}

Hy vọng điều này sẽ giúp bạn.


0

Trên thực tế, cách dễ nhất để khắc phục điều này chỉ là di chuyển đối tượng của bạn trước khi mã Javascript nó hoạt động với tôi. Tôi đoán trong đối tượng trả lời của bạn được tải sau mã 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

Kiểm tra xem bạn không ghi đè window.self

Vấn đề của tôi: Tôi đã tạo ra một thành phần và viết self = thisthay vì var self = this. Nếu bạn không sử dụng từ khóa var, JS sẽ đặt biến đó vào đối tượng cửa sổ, vì vậy tôi ghi đè lên window.selfnguyên nhân gây ra lỗi này.


0

Đây là bản chỉnh sửa của một bài đăng đã bị xóa trước đó để chứa nội dung của câu trả lời được liên kết, trong chính câu trả lời. Mục đích để xuất bản lại câu trả lời này là hoạt động như một PSA cho người dùng React 0.9+, những người cũng đã vấp phải vấn đề này.

bài chỉnh sửa gốc


Cũng gặp lỗi này khi sử dụng ReactJS trong khi theo dõi bài đăng trên blog này . Nhận xét của sahat ở đây đã giúp - xem nội dung bình luận của sahat bên dưới.

Lưu ý cho Phản ứng> = 0,9

Trước v0.9, nút DOM được truyền vào làm đối số cuối cùng. Nếu bạn đang sử dụng cái này, bạn vẫn có thể truy cập nút DOM bằng cách gọi this.getDOMNode ().

Nói cách khác, thay thế tham số rootNode bằng this.getDOMNode () trong phiên bản React mới nhất.


0

Thất bại của tôi là sử dụng

zoomLevel

như một lựa chọn, thay vì lựa chọn chính xác

zoom


0

Trong trường hợp tôi đang xử lý, div bản đồ được hiển thị có điều kiện tùy thuộc vào vị trí có được công khai hay không. Nếu bạn không thể chắc chắn liệu div canvas của bản đồ có ở trên trang hay không, chỉ cần kiểm tra xem bạn document.getElementByIdcó trả lại một phần tử không và chỉ gọi bản đồ nếu nó xuất hiện:

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

-2

Vấn đề ở đây là liên kết API không có thông số key:

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

Cách đó hoạt động tốt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.