在Google';s API javascript示例
在Google为其API提供的各种javascript示例(例如)中,他们使用以下代码从html加载脚本:在Google';s API javascript示例,javascript,google-api,Javascript,Google Api,在Google为其API提供的各种javascript示例(例如)中,他们使用以下代码从html加载脚本: <script async defer src="https://apis.google.com/js/api.js" onload="this.onload=function(){};handleClientLoad()" onreadystatechange="if (this.readyState === 'complete') this.onload()"
<script async defer src="https://apis.google.com/js/api.js"
onload="this.onload=function(){};handleClientLoad()"
onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>
我的理解是,async/defer
告诉浏览器什么时候加载和执行脚本,这两者之间有些矛盾。我有几个问题:
async
和defer
有什么意义
背景onload
事件中,为什么他们首先将空函数(function(){};
)分配给事件
在调用handleClientLoad()之前谢谢。这一点在中得到了很好的介绍,其中包括以下方便的图形: 一,。在此上下文中同时使用async和defer的意义是什么 如果浏览器支持
async
,它将忽略defer
,并执行异步工作。如果不支持,但支持延迟,则改为延迟。如果不支持这两种方法,脚本将阻止DOM解析,但所有现代浏览器都至少支持一种
2.谷歌为什么选择使用这种技术?它是否有任何性能或其他好处
async
在不阻止DOM解析和呈现的情况下获取脚本,并在可用时立即运行脚本,即使DOM解析和呈现仍在进行中defer
还将避免阻止DOM解析和呈现,但在解析完成之前(例如,可能稍后)不会运行脚本
三,。在onload事件中,为什么在调用handleClientLoad()
之前,他们首先为事件分配一个空函数(function(){};
)
如果您查看onreadystatechanged
,这一点就很清楚了:它基本上确保了handleClientLoad
只由GAPI调用一次,而不是潜在的两次(一次由onload
调用,一次由onreadystatechanged
调用)
四,。如果我想将整个javascript移动到一个单独的js文件中,那么加载这两个脚本的最佳方法是什么?因为新的js文件将依赖于api.js,不能异步加载
嗯,它可以异步加载,您只需使用api.js
处理竞争条件即可。我可能会:
脚本
标记加载api.js上方的内联脚本中设置handleClientLoad
,如下所示:
var clientLoaded = false;
function handleClientLoad() {
if (!clientLoaded &&
typeof mainScriptLoad !== "undefined" &&
typeof gapi !== "undefined") {
clientLoaded = true;
mainScriptLoad();
}
}
mainScriptLoad
放在单独的文件中handleClientLoad
- 如果您的脚本首先运行,它将调用
,但是handleClientLoad
将看到GAPI尚未加载,并且不会执行任何操作;稍后,当GAPI加载时,它将调用handleClientLoad
,这将调用handleClientLoad
,因为一切都准备好了mainScriptLoad
- 如果脚本在GAPI加载后运行,它将调用
,但是handleClientLoad
将看到主脚本尚未加载,并且不会尝试调用它。稍后,当脚本加载并调用handleClientLoad
时,handleClientLoad
将调用handleClientLoad
,因为一切就绪mainScriptLoad
onload
和onreadystatechange
?为了支持不同的浏览器?@danielv:是的script
标记没有用于引发时间迷雾中的load
事件,而是引发了onreadystatechanged
事件。@danielv:谢谢!固定的。