如何检查Google Maps是否完全加载?

319

我正在将Google地图嵌入我的网站中。一旦Google地图加载完成,我需要启动一些JavaScript进程。

有没有一种方法可以自动检测Google地图何时完全加载,包括瓦片下载和所有内容?

存在一个tilesloaded()方法,旨在实现此任务,但是它不起作用


2
“tilesloaded”事件对我有效。它在页面加载和移动地图时触发。在您的地图上,它是不是只是不一致,还是从未起作用? - Chris B
1
不行,绝对不行。正如它所说的那样,“tilesloaded”将在每次加载新瓦片时触发,这意味着它不仅会在第一次加载时触发,而且还会在每次拖动地图到尚未加载瓦片的位置时触发。 - Aivus
取决于您使用 addListener() 还是 addListenerOnce()。您对 addListener() 的理解是正确的 - 这就是为什么我使用 google.maps.event.addListenerOnce(map, 'tilesloaded', function() { - Christoph Lösch
13个回答

637

使用GMaps v3时,这一直困扰着我。

我找到了一个这样的解决方法:

google.maps.event.addListenerOnce(map, 'idle', function(){
    // do something only the first time the map is loaded
});

当地图进入空闲状态(所有内容加载完毕或加载失败),会触发“idle”事件。我发现使用addListenerOnce方法并在闭包中编写代码,比使用tilesloaded/bounds_changed更可靠,因为在第一次触发“idle”时执行闭包中的代码,然后解除事件监听。

另请参阅Google Maps参考文档中的事件部分


15
当地图进入空闲状态(不再加载任何内容)时,将触发该事件。有时由于网络连接差,可能会出现一些未能加载的地图块,因此即使存在这样的缺失部分,最终也会触发空闲事件。如果您需要确保地图完整,没有缺少的地图块等,则应寻找其他方式(例如“tilesloaded”事件)。 - ddinchev
17
对我来说它不起作用了... 在我的地图上显示任何东西之前就出现了触发器。 - zsitro
17
比瓦片加载/显示更早地触发。 - zbr
12
在Chrome和Firefox浏览器中,当脚本加载完成但尚未显示任何图块时,该事件会始终触发,即使在快速连接下可能不明显,但我很幸运拥有一个非常慢的连接。然而,似乎“tilesloaded”事件可以正常工作。 - Xananax
2
谢谢你提供的解决方案 - 我认为这正是我所需要的。我无法理解的是,为什么谷歌没有放置一个简单的准备好的钩子? :-O - hasse
显示剩余11条评论

67

我正在创建HTML5移动应用程序,注意到当地图对象被创建和渲染时(即使它不可见),idlebounds_changedtilesloaded事件会触发。

为了使我的地图在第一次显示时运行代码,我进行了以下操作:

google.maps.event.addListenerOnce(map, 'tilesloaded', function(){
    //this part runs when the mapobject is created and rendered
    google.maps.event.addListenerOnce(map, 'tilesloaded', function(){
        //this part runs when the mapobject shown for the first time
    });
});

5
第一个 tilesloaded 函数对我很有效,但第二个 tilesloaded 函数从未在我的情况下运行。 - Goose
我遇到了“未捕获的引用错误:map未定义”的问题。我尝试过延迟运行脚本,也在其他脚本的末尾运行,但似乎都没有起作用。 - Sam Willis
1
如果你在事件处理程序内部定义事件处理程序,那么你会遇到麻烦。我强烈建议你不要这样做,这里有一个稍微不那么hacky的替代方案,可以实现类似的功能:https://gist.github.com/cmawhorter/a1b0b6a6b73678b97920f748ebca244b - Cory Mawhorter
@SamWillis 很可能是因为你的 map 对象没有被实例化,我知道你说你在最后添加了它,但这就是错误的意思...它找不到你的 map 对象。 - Uriahs Victor

24

tilesloaded是唯一一个正确等待KML图层全部渲染完成的解决方案。 - smirkingman
1
这对我有用,但每次操作地图时它都会触发,最终我不得不使用 google.maps.event.addListenerOnce(map, 'tilesloaded', function(){},以便只触发一次。addListenerOnce 似乎不支持 map - Uriahs Victor

16
如果您正在使用Maps API v3,则已经发生了变化。
在版本3中,你需要为bounds_changed事件设置监听器,该事件将在地图加载时触发。一旦该事件被触发,请删除监听器,因为您不希望每次视口边界改变时都被通知。
随着V3 API的演变,这可能会发生变化 :-)

2
我发现与寻找“tilesloaded”事件相比,这对我来说不太可靠。 - TMC

7
如果您正在使用Web组件,那么他们会提供以下示例:
map.addEventListener('google-map-ready', function(e) {
   alert('Map loaded!');
});

4
评论很糟糕,错误之处太多,不知从何处开始。 - nights
1
你为什么说“糟糕的评论,错误之处太多,我不知道从哪里开始”? - Phillip Senn
4
为什么要使用不同的框架来提供解决方案,而不是只使用谷歌地图? - nights
因为可能更好? - Phillip Senn
2
HAHAHAHA @nights - chesscov77

5

GMap2::tilesloaded() 是你需要查找的事件。

请参阅 GMap2.tilesloaded 以获取相关信息。


我已经阅读了很多关于tilesloaded()事件的内容,似乎它在触发时极其不一致。还有其他选择吗? - happygilmore892

3

变量 map 是 GMap2 类型的对象:

    GEvent.addListener(map, "tilesloaded", function() {
      console.log("Map is fully loaded");
    });

1

针对Google Maps V3,在检查谷歌地图完全加载时使用。

诀窍是这里所有提交的组合。

首先,您必须创建地图示例:

let googleMap = new google.maps.Map(document.getElementById(targetMapId), 
{
        zoom: 17,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        streetViewControl: false,
        styles: [
          {
            featureType: "poi",
            elementType: "labels",
            stylers: [
              {visibility: "off"}
            ]
          }
        ],
      });

然后您需要设置一个默认位置来加载它... 它可以放在任何地方

googleMap.setCenter({
        lat: 26.12269,
        lng: -80.130172
      });

最后,一旦它完成加载该位置的瓷砖,您可以通过“tilesloaded”事件处理代码,这些代码可以包括重新定位地图、放置标记等等。

这确保了在对地图进行操作之前,地图已经被加载。

google.maps.event.addListenerOnce(googleMap, 'tilesloaded', function(){
// do something only the first time the map is loaded
});

其他人也建议使用"空闲"事件,但是对我来说,这并不是很有效,因为有时候成功,有时候失败。

google.maps.event.addListenerOnce(googleMap, 'idle', function(){
// do something only the first time the map is loaded
});

然而,当我使用“tilesloaded”时,虽然我会得到一个快速的闪烁,然后跳转到正确的地图视图,但它总是有效的...所以我选择了两害相权取其轻的方法


0
在我的情况下,瓷砖图像是从远程URL加载的,并且在渲染图像之前触发了“tilesloaded”事件。
我用以下不太优雅的方式解决了这个问题。
var tileCount = 0;
var options = {
    getTileUrl: function(coord, zoom) {
        tileCount++;
        return "http://posnic.com/tiles/?param"+coord;
    },
    tileSize: new google.maps.Size(256, 256),
    opacity: 0.5,
    isPng: true
};
var MT = new google.maps.ImageMapType(options);
map.overlayMapTypes.setAt(0, MT);
google.maps.event.addListenerOnce(map, 'tilesloaded', function(){
    var checkExist = setInterval(function() {
        if ($('#map_canvas > div > div > div:nth-child(1) > div:nth-child(1) > div:nth-child(1) > div:nth-child(2) > div > div').length === tileCount) {
            callyourmethod();
            clearInterval(checkExist);
        }
    }, 100); // check every 100ms
});

0

这些天你知道地图是否准备好了:

void _onMapCreated(GoogleMapController controller) {
    this.controller = controller;
    _mapIsReady=true; //create this variable
  }

从地图小部件调用此方法

return GoogleMap(
              myLocationEnabled: true,
              //markers: markers,
              markers: Set<Marker>.of(markers.values),
              onMapCreated: _onMapCreated,
              initialCameraPosition: CameraPosition(

                target: _initialPosition,
                zoom: 5.0,
              ),
            );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接