如何在页面加载后加载Google地图的外部JavaScript?

31
我将提供更多信息来解释我的情况。我正在使用PhoneGap构建一个应用程序,以在iOS上部署。我有一个视图/页面,用户将导航到(不使用ajax),它将加载所需的google地图js脚本并调用cordova地理位置api。
我的问题是加载google地图脚本:
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=XXXXXXXXXX&sensor=true"></script>

加载时间太长,导致页面渲染时间长达近3秒。我希望在页面完全渲染后再延迟加载外部脚本。将脚本放在页面底部,紧挨着标签也没有任何帮助。
我曾尝试使用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.

我已经在实际脚本标签中尝试了'defer'和'async',但仍然会抛出相同的错误。其他加载外部JS文件的方法也会导致相同的错误消息。

是否有可能的解决方法来解决这个问题?我甚至不知道错误声明是什么意思...


6
请参见文档中的异步加载API部分 - geocodezip
4
-1?那有点严厉。有人愿意自愿提供更多的信息来解释原因吗?@geocodezip,我已经尝试了你建议的方法。事实上,我已经尝试了几种方法,但它们都不起作用。我已经找出了核心问题,我正在加载的远程谷歌api脚本实际上正在加载另一个脚本,所以是的,我不能异步调用一个正在异步调用另一个脚本的脚本。一旦我得到解决方案,我会发布它。 - Ryan Coolwebs
3
请再次阅读文档,其中有一个回调参数,您可以异步加载API并在准备好使用时调用它(运行定义为回调的函数)。 - Dr.Molle
1
好的,是的,我现在明白了。我再试了一下,并且只是为回调函数放了一个空函数(因为我不想在回调时运行任何函数)。一个按钮加载地图和位置。 - Ryan Coolwebs
你最好从问题的代码示例中删除API密钥。 - Paul Kozlovitch
谢谢提醒,@Paul。已经移除API。 - Ryan Coolwebs
4个回答

13

我尝试了我的解决方案,它有效。

使用jQuery在DOM准备就绪时运行脚本。

基本上,不要像这样使用你的function initialize

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

请执行以下操作:

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

不再需要使用google.maps.event.addDomListener(window, 'load', initialize);

不再需要。


编辑 #1 :我目前遇到了一些类似于你的问题,我认为我现在有一个更好的解决方案可以提供给你。

在你的JS文件中,在initialize函数之后,放置以下函数:

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);
    };

它的基本作用是先调用地图加载器,然后在加载器准备就绪后调用地图。
接下来使用刚刚编写的内容:

在你的html页面中:

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

获取该脚本后,您可以使用其变量,并在DOM准备好并完成加载后调用所需变量ready
建议将此代码放置在html页底部,在body标签闭合后。

我有同样的问题,但我无法让它工作。在jQuery JS中,我一直收到“未捕获的SyntaxError:意外的标记”。这很难调试。我使用jQuery“load”获取页面内容,并且Google地图位于加载的内容上。 - Andy Swift
2
最终,我通过使用“setTimeout”将initialize()函数延迟一秒后执行来使其正常工作。 - Andy Swift

4

//使用jQuery的getScript函数

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

说明:

首先加载包含初始化函数的外部脚本,并在回调时使用callback参数加载谷歌地图API,其值为initialize。


4

我试图在一个部分视图中加载谷歌地图,这将作为标准页面(这不是问题)或引导模态窗口加载,但无法成功并出现以下错误(对于模式):

在异步加载的外部脚本中执行'write'操作失败:除非显式打开,否则不可能将其写入文档。

我没有使用脚本,因为我正在从我的数据模型动态调用标记(或者至少我还没有达到那个阶段)。 无论如何,感谢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>

还有一个想法,我不得不从我的模态中删除淡入淡出效果,这与其他人评论的情况相一致,他们不得不将执行延迟一秒钟。我尝试了resizetarget修复和所有这些方法,但都没有成功。

这个问题需要进行大量的试错,希望能为某些人节省时间。


-2

你需要在body标签结束后加载js文件。


我尝试了 document.getElementsByTagName('html')[0].appendChild(...),在谷歌浏览器中出现了相同的错误。 - OZZIE
@ozzie,请尝试使用document.getElementsByTagName('body')[0].appendChild(...) - standac

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