如何在页面加载后加载谷歌地图外部JavaScript?

时间:2022-10-12 15:40:02

I will provide more information to explain my situation. I am building an application with PhoneGap for deployment on iOS. I have a a view/page that user will navigate to (not using ajax) that will load google maps js scripts that are needed and do a call to the cordova geolocation api.

我将提供更多信息来解释我的情况。我正在使用PhoneGap构建一个应用程序,以便在iOS上进行部署。我有一个用户将导航到(不使用ajax)的视图/页面,它将加载所需的google maps js脚本并调用cordova geolocation api。

My issue is that loading the google maps script:

我的问题是加载谷歌地图脚本:

<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=XXXXXXXXXX&sensor=true"></script>

Takes too long to load and stops the page from rendering for up to almost 3 seconds. I want to defer the load of the external script until the page has fully rendered. Putting the script down at the bottom of the page just before does not help at all.

加载时间过长会使页面停止渲染最多3秒钟。我想推迟外部脚本的加载,直到页面完全呈现。在以前将脚本放在页面底部根本没有用。

I was attempting to use getScript() but it will not work and throws the following error in debug console:

我试图使用getScript()但它不起作用并在调试控制台中抛出以下错误:

Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.

I have tried 'defer' and 'async' in the actual script tag, but that throws the same error as well. Other methods of loading external JS files lands me with the same error message.

我在实际的脚本标记中尝试了'defer'和'async',但是也会抛出相同的错误。其他加载外部JS文件的方法给我带来了相同的错误信息。

Is there any possible workaround to this problem. I don't even know what the error statement means...

是否有任何可能的解决方法来解决此问题。我甚至不知道错误陈述的含义......

4 个解决方案

#1


13  

I tried this solution of mine and it worked.

我尝试了我的这个解决方案并且有效。

Run the script on dom ready using jquery.

使用jquery在dom上运行脚本。

basically instead of using your function initialize like this :

基本上没有使用你的函数初始化如下:

function initialize(){
/*You code */
}

do this:

做这个:

$(function(){
/*You code */
})

And no need for google.maps.event.addDomListener(window, 'load', initialize);

并且不需要google.maps.event.addDomListener(window,'load',initialize);

Anymore.

了。


Edit #1 : I am currently facing some familiar problem to yours, and I think I have a better solution to you now.

编辑#1:我目前正面临一些熟悉的问题,我想我现在有更好的解决方案。

in your JS file, after your initialize function , put this function:

在你的JS文件中,在你的初始化函数之后,把这个函数放到:

var ready: // Where to store the function

    ready = function() {
      var script = document.createElement('script');
      script.type = 'text/javascript';
      script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp&' + 'libraries=places&'+'callback=initialize';
      document.body.appendChild(script);
    };

What it basically does is that it calls for the map loader first, and then calls for the map after the loader is ready.
And afterwards make use of you what just wrote with this

它基本上做的是它首先调用地图加载器,然后在加载器准备好之后调用地图。然后再利用你刚才写的东西

In your html page :

在你的html页面中:

<script>
    $.getScript("You js file path",function(){
          $(document).ready(ready);
    });
</script>

And this gets the script so you can use its variables, and then call the variable you need ready after the DOM is ready and finished loading.

这将获取脚本,以便您可以使用其变量,然后在DOM准备好并完成加载后调用您需要的变量。

I recommend putting this at the bottom of your html page,after the body closes.

我建议在主体关闭后将它放在html页面的底部。

#2


4  

I was trying to load google maps in a partial view that would load as a standard page (which wasn't the problem) or a bootstrap modal and having no luck with this error (for the modal):

我试图在部分视图中加载谷歌地图,这将加载为标准页面(这不是问题)或引导模式,并且没有运气这个错误(对于模态):

failed to execute 'write' on 'document': it isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.

无法在'document'上执行'write':除非明确打开,否则无法从异步加载的外部脚本写入文档。

I'm not using scripts because I'm dynamically calling the markers from my data model (or I at least I haven't gotten that far yet). Anyway, thanks to Hamza, I was able to get it working with this:

我没有使用脚本,因为我正在从我的数据模型中动态调用标记(或者至少我还没有那么远)。无论如何,多亏了Hamza,我能够得到它:

<div id="map-canvas" style="width:512px;height:464px;"></div>

@*<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js"></script>*@
    <script type="text/javascript">
    function initialize() {
        var mapDiv = document.getElementById('map-canvas');

        var mapOptions = {
            zoom: 1,
            minzoom: 1,
            mapTypeControl: true,
            zoomControl: true,
            scaleControl: true,
            streetViewControl: true,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        }

        var map = new google.maps.Map(mapDiv, mapOptions);

        //var markers = getMarkers(map);
        map.setCenter({ lat: 0, lng: 0 });

    };

    //google.maps.event.addDomListener(window, 'load', initialize);
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places&callback=initialize';
    document.body.appendChild(script);
</script>

One more thought, I had to remove the fade from my modal as well which correlates to someone else commenting they had to delay the execution by a second. I tried the resizetarget fix and all that with no luck as well.

还有一个想法,我不得不从我的模态中删除淡入淡出,这与其他人评论相关,他们必须将执行延迟一秒钟。我尝试了resizetarget修复,所有这些都没有运气。

Lots of trial and error on this one, hopefully saves someone some time.

对此有很多反复试验,希望能节省一些时间。

#3


2  

//Using jQuery's getScript function

//使用jQuery的getScript函数

$.getScript('[js containing the initialize function]',function(){
    $.getScript('https://maps.googleapis.com/maps/api/js?v=3.exp&callback=initialize');
}); 

Explanation:

说明:

First load your external script containing the initialize function and upon callback, load the google map API with callback equals to initialize.

首先加载包含initialize函数的外部脚本,然后在回调时,使用callback equals初始化来加载google map API。

#4


-2  

You need to load the js file after the body tag end.

您需要在body标记结束后加载js文件。

#1


13  

I tried this solution of mine and it worked.

我尝试了我的这个解决方案并且有效。

Run the script on dom ready using jquery.

使用jquery在dom上运行脚本。

basically instead of using your function initialize like this :

基本上没有使用你的函数初始化如下:

function initialize(){
/*You code */
}

do this:

做这个:

$(function(){
/*You code */
})

And no need for google.maps.event.addDomListener(window, 'load', initialize);

并且不需要google.maps.event.addDomListener(window,'load',initialize);

Anymore.

了。


Edit #1 : I am currently facing some familiar problem to yours, and I think I have a better solution to you now.

编辑#1:我目前正面临一些熟悉的问题,我想我现在有更好的解决方案。

in your JS file, after your initialize function , put this function:

在你的JS文件中,在你的初始化函数之后,把这个函数放到:

var ready: // Where to store the function

    ready = function() {
      var script = document.createElement('script');
      script.type = 'text/javascript';
      script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp&' + 'libraries=places&'+'callback=initialize';
      document.body.appendChild(script);
    };

What it basically does is that it calls for the map loader first, and then calls for the map after the loader is ready.
And afterwards make use of you what just wrote with this

它基本上做的是它首先调用地图加载器,然后在加载器准备好之后调用地图。然后再利用你刚才写的东西

In your html page :

在你的html页面中:

<script>
    $.getScript("You js file path",function(){
          $(document).ready(ready);
    });
</script>

And this gets the script so you can use its variables, and then call the variable you need ready after the DOM is ready and finished loading.

这将获取脚本,以便您可以使用其变量,然后在DOM准备好并完成加载后调用您需要的变量。

I recommend putting this at the bottom of your html page,after the body closes.

我建议在主体关闭后将它放在html页面的底部。

#2


4  

I was trying to load google maps in a partial view that would load as a standard page (which wasn't the problem) or a bootstrap modal and having no luck with this error (for the modal):

我试图在部分视图中加载谷歌地图,这将加载为标准页面(这不是问题)或引导模式,并且没有运气这个错误(对于模态):

failed to execute 'write' on 'document': it isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.

无法在'document'上执行'write':除非明确打开,否则无法从异步加载的外部脚本写入文档。

I'm not using scripts because I'm dynamically calling the markers from my data model (or I at least I haven't gotten that far yet). Anyway, thanks to Hamza, I was able to get it working with this:

我没有使用脚本,因为我正在从我的数据模型中动态调用标记(或者至少我还没有那么远)。无论如何,多亏了Hamza,我能够得到它:

<div id="map-canvas" style="width:512px;height:464px;"></div>

@*<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js"></script>*@
    <script type="text/javascript">
    function initialize() {
        var mapDiv = document.getElementById('map-canvas');

        var mapOptions = {
            zoom: 1,
            minzoom: 1,
            mapTypeControl: true,
            zoomControl: true,
            scaleControl: true,
            streetViewControl: true,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        }

        var map = new google.maps.Map(mapDiv, mapOptions);

        //var markers = getMarkers(map);
        map.setCenter({ lat: 0, lng: 0 });

    };

    //google.maps.event.addDomListener(window, 'load', initialize);
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places&callback=initialize';
    document.body.appendChild(script);
</script>

One more thought, I had to remove the fade from my modal as well which correlates to someone else commenting they had to delay the execution by a second. I tried the resizetarget fix and all that with no luck as well.

还有一个想法,我不得不从我的模态中删除淡入淡出,这与其他人评论相关,他们必须将执行延迟一秒钟。我尝试了resizetarget修复,所有这些都没有运气。

Lots of trial and error on this one, hopefully saves someone some time.

对此有很多反复试验,希望能节省一些时间。

#3


2  

//Using jQuery's getScript function

//使用jQuery的getScript函数

$.getScript('[js containing the initialize function]',function(){
    $.getScript('https://maps.googleapis.com/maps/api/js?v=3.exp&callback=initialize');
}); 

Explanation:

说明:

First load your external script containing the initialize function and upon callback, load the google map API with callback equals to initialize.

首先加载包含initialize函数的外部脚本,然后在回调时,使用callback equals初始化来加载google map API。

#4


-2  

You need to load the js file after the body tag end.

您需要在body标记结束后加载js文件。