简体   繁体   English

如何在加载 google.maps.OverlayView 派生类之前等待加载 google maps API

[英]How to wait till the google maps API has loaded before loading a google.maps.OverlayView derived class

I have a separate label.js file in which I have defined a custom overlay.我有一个单独的 label.js 文件,我在其中定义了一个自定义叠加层。 It uses the google.maps.OverlayView as its prototype:它使用 google.maps.OverlayView 作为原型:

Label.prototype = new google.maps.OverlayView();

I am not sure where to place the script tags for this js file in my index.html file.我不确定在 index.html 文件中将此 js 文件的脚本标记放在何处。 If I place the script tags below the google maps loading tag like so:如果我将脚本标签放在谷歌地图加载标签下方,如下所示:

....
        <script async defer
            src="https://maps.googleapis.com/maps/api/js?...
        </script>
        <script src="js/label.js"></script>
    </body>
</html>

The label.js file is loaded immediately while the maps api has not yet loaded causing an error. label.js 文件会立即加载,而 maps api 尚未加载会导致错误。

I currently solve this by manually loading the JS in my maps loaded callback:我目前通过在我的地图加载回调中手动加载 JS 来解决这个问题:

function initMap() {
    gMap = new google.maps.Map(document.getElementById(strMapDivName), {
        center: {lat: 21, lng: 78},
        mapTypeId: google.maps.MapTypeId.HYBRID,
        zoom: 6,
        heading: 90,
        tilt: 0
    });

    // Load label.js afterwards so we can be sure that the google maps api has loaded
    var fileref=document.createElement('script')
    fileref.setAttribute("type","text/javascript")
    fileref.setAttribute("src", "js/label.js")

    document.getElementsByTagName("head")[0].appendChild(fileref)

}

Is this the best way to solve this?这是解决这个问题的最好方法吗?

You should include a callback function in the API call. 您应该在API调用中包含一个回调函数。

<script async defer src="https://maps.googleapis.com/maps/api/js?callback=myFunction"></script>

You can then include any maps related code within the callback function: 然后,您可以在回调函数中包含所有与地图相关的代码:

function myFunction() {
  // Your code here
}

If you need to wait until the map is "ready" ie, the map is displayed with the map options and "idle" you can use: 如果您需要等到地图“就绪”,即显示地图时带有地图选项和“空闲”,则可以使用:

google.maps.event.addListenerOnce(map, 'idle', function () {
    // map is ready
});

But you should still include this within the callback function. 但是您仍然应该在回调函数中包括它。

Here is a generic that I made and works for me. 这是我制作并为我工作的通用名称。

1) Define the function you want to execute after Google maps is loaded 1)定义要在加载Google地图后执行的功能

function ToExecuteAfterLoaded()
  {
  // Doing something here ///
  console.log("Executing this function"); // per example //
  }

2) Waiting function 2)等待功能

function WhenGoogleLoadedDo(fnt)
   {
   if(typeof google != 'undefined')
      fnt();
   else
      setTimeout(function()
         {(function(fnt)
            {
            WhenGoogleLoadedDo(fnt)
            })(fnt)}, 500); // You can set timer as you wish //
   }

3) Call the ToExecuteAfterLoaded like this in your script 3)在脚本中像这样调用ToExecuteAfterLoaded

WhenGoogleLoadedDo(ToExecuteAfterLoaded);

I know it's too late, but I use this code below 我知道为时已晚,但是我在下面使用此代码

var mapWaitCount = 0;
var mapWaitMax = 5;

function map_load(param1, param2, ...) { // if you need any param
    mapWaitCount++;
    // if api is loaded
    if(typeof google != 'undefined') {
        // your code here 
    }
    // try again if until maximum allowed attempt
    else if(mapWaitCount < mapWaitMax) {
        console.log('Waiting attempt #' + mapWaitCount); // just log
        setTimeout(function() { map_load(); }, 1000);
    }
    // if failed after maximum attempt, not mandatory
    else if(mapWaitCount >= mapWaitMax) {
        console.log('Failed to load google api');
    }
}

map_load(param1, param2, ...) { // if you need any param

It uses timeout to wait for the load, and after several attempts it will be stopped 它使用超时来等待加载,经过几次尝试后它将停止

What about wrapping your custom label with DOMContentLoaded? 如何用DOMContentLoaded包装自定义标签?

      document.addEventListener("DOMContentLoaded", function(event) {
            Label.prototype = new google.maps.OverlayView();
      });

Reference: https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded 参考: https : //developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded

Updating an old question; 更新一个老问题; in React I used the NPM module: load-google-maps-api 在React中,我使用了NPM模块: load-google-maps-api

I started barking down the tree of creating that myself, before realising this existed and could save some time. 在意识到这一点的存在并可以节省一些时间之前,我开始吠叫自己创建那棵树。

It's going to load the maps API in a promise format and so you can provide a callback function for after load. 它将以Promise格式加载maps API,因此您可以为加载后提供回调函数。

loadGoogleMapsApi().then(function (googleMaps) {
  new googleMaps.Map(document.querySelector('.map'), {
    center: {
      lat: 40.7484405,
      lng: -73.9944191
    },
    zoom: 12
  })
}).catch(function (error) {
  console.error(error)
})

Typescript way of doing打字稿的做事方式

You can now use the Google Maps JavaScript API Loader library您现在可以使用Google Maps JavaScript API Loader 库

  1. run npm i @googlemaps/js-api-loader运行npm i @googlemaps/js-api-loader
  2. Use the loader使用装载机
const loader = new Loader({
  apiKey: "",
  version: "weekly"
});

JavaScript way JavaScript 方式

  1. Subscribe to the loader promise订阅加载器承诺
loader
  .load()
  .then((google) => {
    new google.maps.Map(document.getElementById("map"), mapOptions);
  })
  .catch(e => {
    // do something
  });

Libraries way Ex: angular图书馆方式例如:角度

  1. Subscribe to the loader promise订阅加载器承诺
isMapApiLoaded?: boolean

loader
  .load()
  .then((google) => {
     this.isMapApiLoaded = true
  })
  .catch(e => {
    // do something
  });
  1. Show the map only when loaded仅在加载时显示地图
<google-map *ngIf="isMapApiLoaded"> 
  <!-- ... -->
</google-map>

Additional (singleton)附加(单件)

  1. You could use the loader in a service that you then import globally您可以在服务中使用加载器,然后全局导入
export class MapLoaderService {
  onMapApiDidLoad$: BehaviorSubject<boolean> = new BehaviorSubject(null)
  
  private _initLoader() {
    this.mapLoader
      .load()
      .then((google) => {
        this.onMapApiDidLoad$.next(true)
      })
      .catch((e) => {
        this.onMapApiDidLoad$.next(false)
      })
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM