2012-10-22 96 views
11

我想异步的谷歌地图api的JavaScript。异步加载JavaScript与document.write

所以,正常的脚本标签工作<script src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>

但是,下面的异步版本没有。

(function() { 
    var gmap = document.createElement('script'); gmap.type = 'text/javascript'; gmap.async = true; 
    gmap.src = 'https://maps.googleapis.com/maps/api/js?sensor=false'; 
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(gmap, s); 
})(); 

经过一些断点+检查动作后,我发现这条线在异步模式下无法正确运行。

document.write('<' + 'script src="' + src + '"' + 
' type="text/javascript"><' + '/script>'); 

在同步模式中的文档对象是一个“HTMLDocument的”,但在异步模式是一种“#document”代替。加载页面后,文档对象发生了某些情况。思考?

干杯。

更新:这个问题是关于为什么document.write没有被解雇,而不是异步加载谷歌地图API。如果你在这一行设置了一个断点,你可以看到document.write函数存在。这与document.write是否为本地事实有什么关系?

回答

7

document.write不能从异步脚本中调用,因为它从文档中分离出来,因此你的JS解析器不知道把它放在哪里。充其量,浏览器会忽略它。在最坏的情况下,它可以覆盖当前文档的顶部(如在文档加载完成后调用document.write的情况下)。

不幸的是,唯一的答案是重写脚本,这在google api的情况下可能不是一个可行的选项。

+0

谢谢。我在这一行做了断点,并尝试记录自己。它确实找到了write()函数,这就是奇怪的原因。如果写入函数被分离,那么为什么它不是未定义的? – user1736525

+0

谷歌是一个笑话 – neaumusic

2

当您在脚本URL中使用参数callback时,脚本不会使用write(),您将能够异步加载API。

参见:https://developers.google.com/maps/documentation/javascript/tutorial?hl=en#asynch

+0

是的,我有回调,但我遇到了另一个问题在jquery移动,它加载谷歌地图API多次。我不喜欢警告信息。 – user1736525

+2

如果您不喜欢该警告,请多次加载该API。 –

+0

这是使用jqm ajax模式的asp mvc中的jquery mobile。因此,加载API一次而不是使用jqm事件似乎更清晰。 – user1736525

4

我在异步加载亚马逊广告时遇到了一个非常类似的问题。我能够通过改变其行为得到document.write在我的应用程序针对这些情况近似(在这种情况下$指的jQuery):

document.write = function(content) { 
    if (document.currentScript) { 
    var src = document.currentScript.src 
     .replace(/\#.*$/, '') 
     .replace(/\?.*$/, '') 
     .replace(/^.*\/\//, ''); 
    setTimeout(function() { 
     var script = $('script').filter(function() { 
     var scriptSrc = $(this).attr('src'); 
     return scriptSrc && scriptSrc.indexOf(src) !== -1; 
     }); 
     $('<div></div>') 
      .addClass('doc-write') 
      .html(content) 
      .insertAfter(script); 
    }, 0); 
    } else { 
    HTMLDocument.prototype.write.apply(document, arguments); 
    } 
}; 

这种方法还有待改进,但它工作得很好满足我的需求。希望你会发现它很有用。

+0

刚刚投了票,但现在意识到这是不支持在IE 11中。任何建议? – downatone

+0

使用带有初始api加载的'callback = somefunction'参数 – neaumusic

0

在这里添加评论,因为我在这个问题上挣扎了很多。当异步加载脚本时(例如通过点击按钮),请确保按照site上的说明刚好

当我没有给出回调值时,我第一次得到了document.write错误。回拨后,我得到window.initialize错误,因为......呃......我的代码中没有初始化函数。我改变了我的函数名称(类似于loadMap)并开始工作。

说实话,只需从网站复制代码,它应该工作。将window.onload替换为触发该功能所需的任何内容。