Google MAP API未捕获的TypeError:无法读取null的属性“ offsetWidth”


204

我正在尝试将Google MAP API 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>

当我运行这段代码时,浏览器会这样说。

未捕获的TypeError:无法读取null的属性'offsetWidth'

我不知道,因为我遵循了本教程中给出的指导

你有什么线索吗?

Answers:


317

此问题通常是由于在需要运行JavaScript的javascript运行之前未渲染map div引起的。

您应该将初始化代码放在onload函数中或HTML文件底部的标记之前,以便DOM在执行之前完全呈现(请注意,第二个选项对无效的HTML更为敏感)。

请注意,正如matthewsheets所指出的,这也可能是由div导致的,该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(“ map-canvas”); if(mapExists){//脚本}使一切变得更好。
势在必行的2014年

109

对于可能仍然存在此问题的其他用户,即使尝试了上述建议,在初始化函数中为地图画布使用错误的选择器也可能导致此问题,因为该函数试图访问的对象不存在。仔细检查您的地图ID是否与您的Initialize函数匹配,以及您的HTML还是可能抛出此相同错误。

换句话说,请确保您的ID匹配。;)


3
令人惊讶的是,如何确保这不是问题……直到您仔细检查并意识到自己已在较早的测试中进行了更改,却忘了将其改回。:-)
Charlie Gorichanaz 2014年

28

如果未指定centerzoom在地图选项中也可能会收到此错误。


2
那就是那个!因为我后来在脚本中进行了设置,所以从选项中删除了缩放,并且繁荣,地图将在第一次加载,但是第二次将生成该错误。谢谢!!
伊恩·格兰特

是的,这是我的!变焦但没有中心。只需添加固定的中心即可。
Whelkaholism

1
实际上,他们至少可以在控制台中记录一些消息。谢谢!
马丁·希什科夫,

26

google使用id="map_canvas"id="map-canvas"在示例中,仔细检查并再次仔细检查id:D


23

年,geocodezip的答案是正确的。因此,请按以下方式更改您的代码:(如果您仍然遇到麻烦,或者将来可能还有其他人)

<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和height值,因此其大小为width x 0。一旦我像这样在CSS中设置了这个div的大小

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

一切正常!希望这对某人有帮助。


这正是它对我不起作用的原因。您需要确保CSS与您的地图ID匹配,并且您具有某种初始的宽度/高度组合,否则不会呈现任何内容。回顾一下:1.确保在JavaScript中调用getElementById时,您的html div ID与ID选择器匹配。2.确保CSS具有用于样式化特定地图的代码,例如#map1 {width:200px; 高度:200px;}或类似内容,以便呈现。
塔希尔·哈立德

7

对于更多可能仍然存在此问题的其他人,我使用的是自动关闭<div id="map1" />标签,第二个div没有显示,并且似乎不在dom中。一旦我将其更改为两个打开和关闭标签,<div id="map1"></div>它就会起作用。hth


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

将ID(在所有3个地方)从“ map-canvas”更改为“ map”,即使我已确定ID相同,div的宽度和高度以及代码均不是,但为我固定了它运行直到窗口加载调用之后。不是破折号;除“地图”外,它似乎无法与其他ID一起使用。


4

另外,请确保未在选择器中的列表中放置井号(#)

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

    document.getElementById('map') // good

声明。它不是jQuery。快速提醒一下匆忙的人。


3

我遇到了同样的问题,但是问题是缩放没有在给Google Maps的options对象中定义。


2

如果要在循环中创建多个地图,则如果不存在单个地图DOM元素,它将破坏所有地图。首先,在创建新的Map对象之前检查以确保DOM元素存在。

[...]

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
但是,所有要做的就是停止创建地图,而不是实际修复混乱并创建地图。
Ryan The Leach 2015年

1

如果您恰好正在使用asp.net Webforms,并且正在使用母版页在页面后面的代码中注册脚本,请不要忘记使用map元素(vb.net)的clientID:

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时包括Places库参数。

例如:

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

1

我知道我参加聚会有点晚了,只是想补充一下,当页面中不存在div时也会发生错误。您还可以在加载google maps函数调用之前先检查div是否首先存在。就像是

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
  • 在HTML中设置ng-init = init()
  • 并在控制器中

    使用$ scope.init = function(){...}代替google.maps.event.addDomListener(window,“ load”,init){...}

希望这会帮助你。


0

实际上最简单的解决方法是在Java代码对我起作用之前先移动您的对象。我猜你的答案对象是在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

这是对先前删除的帖子的编辑,以在答案本身中包含链接答案的内容。重新发布此答案的目的是为也遇到此问题的React 0.9+用户充当PSA。

原始编辑帖子


在遵循此博客文章的同时使用ReactJS时也遇到此错误。sahat的评论在这里有所帮助-请在下面查看sahat的评论内容。

ReactReact> = 0.9的注意事项

在v0.9之前,将DOM节点作为最后一个参数传入。如果使用此方法,则仍可以通过调用this.getDOMNode()访问DOM节点。

换句话说,在最新版本的React中将rootNode参数替换为this.getDOMNode()。


0

我的失败是使用

zoomLevel

作为一种选择,而不是正确的选择

zoom


0

在我正在处理的情况下,有条件地渲染了地图div,具体取决于该位置是否公开。如果您不确定地图画布div是否会出现在页面上,只需检查您document.getElementById是否正在返回一个元素,并仅在存在地图时调用该地图:

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

-2

这里的问题是没有key参数的API链接:

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

这样很好。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.