使用 document.write 异步加载 javascript
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13003644/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
async loading javascript with document.write
提问by user1736525
I am trying to async the google map api javascript.
我正在尝试异步 google map api javascript。
So, the normal script tag works <script src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
所以,正常的脚本标签有效 <script src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
But, the following async version doesn't.
但是,以下异步版本没有。
(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);
})();
After some breakpoint+inspect action, I found out that this line doesn't run properly in the async mode.
经过一些断点+检查操作后,我发现该行在异步模式下无法正常运行。
document.write('<' + 'script src="' + src + '"' +
' type="text/javascript"><' + '/script>');
The document object in the sync mode is a "HTMLDocument", but in the async mode is a "#document" instead. Something happened to the document object after the page is loaded. Thoughts?
同步模式下的文档对象是“HTMLDocument”,但异步模式下是“#document”。页面加载后文档对象发生了一些事情。想法?
Cheers.
干杯。
Update:this question is more about why document.write is not fired rather than async load the google map api. If you set a breakpoint on this line, you can see document.write function exists. Does this have anything to do with the fact that document.write is native?
更新:这个问题更多地是关于为什么不触发 document.write 而不是异步加载谷歌地图 api。如果在这一行设置断点,可以看到 document.write 函数存在。这与 document.write 是原生的事实有什么关系吗?
回答by market
document.write
can't be called from an asynchronous script, because it's detached from the document and therefore your JS parser doesn't know where to put it. at best, the browser will ignore it. at worst, it could write over the top of your current document (as in the case of calling document.write after the document has finished loading).
document.write
不能从异步脚本调用,因为它与文档分离,因此您的 JS 解析器不知道将它放在哪里。充其量,浏览器会忽略它。在最坏的情况下,它可能会覆盖当前文档的顶部(就像在文档加载完成后调用 document.write 的情况一样)。
Unfortunately the only answer is to rewrite the script, which in the case of a google api is probably not a viable option.
不幸的是,唯一的答案是重写脚本,这在 google api 的情况下可能不是一个可行的选择。
回答by HandyAndyShortStack
I just ran into a very similar problem when asynchronously loading amazon ads. I was able to get document.write
approximated in my app for these situations by changing its behavior ($
in this case refers to jQuery):
我在异步加载亚马逊广告时遇到了一个非常相似的问题。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);
}
};
This approach could be improved on, but it works well enough for my needs. Hopefully you will find it useful.
这种方法可以改进,但它足以满足我的需要。希望你会发现它很有用。
回答by Dr.Molle
When you use the parameter callback
inside the script-URL, the script doesn't use write()
and you'll be able to load the API asynchronously.
当您callback
在脚本 URL 中使用参数时,脚本不会使用write()
,您将能够异步加载 API。
See: https://developers.google.com/maps/documentation/javascript/tutorial?hl=en#asynch
请参阅:https: //developers.google.com/maps/documentation/javascript/tutorial?hl=en#asynch
回答by Marcelo
Do not use document.write()
, for the reasons explained by market and Dr Molle. Use appendChild()
instead, as done in Google's example of async loading.
document.write()
由于市场和 Molle 博士解释的原因,请勿使用。appendChild()
改为使用,如Google 的异步加载示例中所做的那样。
回答by Plasty Grove
Adding a comment here since I struggled a fair bit with this problem. When loading the script asynchronously (via a button click for example), make sure you follow the instructions exactlyas on the site.
在这里添加评论,因为我在这个问题上遇到了一些困难。异步加载脚本时(例如通过单击按钮),请确保完全按照网站上的说明进行操作。
I first got the document.write
error when I didn't give the callback value. And after giving the callback, I got the window.initialize
error because ... duh ... there was no initialize function in my code. I changed that to my function name (something like loadMap) and it started working.
document.write
当我没有给出回调值时,我首先得到了错误。在给出回调之后,我得到了window.initialize
错误,因为......呃......我的代码中没有初始化函数。我将其更改为我的函数名称(类似于 loadMap)并开始工作。
To be honest, just copy the code from the site and it should work. Replace window.onload
with whatever you need to trigger the said function.
老实说,只需从站点复制代码,它应该可以工作。替换window.onload
为触发上述功能所需的任何内容。