我正在学习使用闭包库,Google提醒我们要仔细使用该库:
这不起作用:
<script src="closure-library/closure/goog/base.js"></script>
<script>
// DON'T DO THIS.
goog.require('goog.dom');
var newHeader = goog.dom.createDom('h1');
</script>
我知道原因,因为goog.require
会动态添加与goog.dom
相关的脚本,并且在goog.dom.xx
脚本尚未下载的情况下会立即执行goog.dom
,然后它会抛出错误。
但我想知道为什么会这样:
<script src="closure-library/closure/goog/base.js"></script>
<script>
goog.require('goog.dom');
</script>
<script>
var newHeader = goog.dom.createDom('h1');
</script>
goog.dom
会在goog.require
之后立即调用,但为什么它不会抛出错误。
这似乎是由于两段代码驻留在两个script
块。
所以我想知道是否有人能解释不同script
块和不同位置(头部或身体内部)的JavaScript执行机制?
Romain的回答者更新:
解析器看到了这个:
<script src="closure-library/closure/goog/base.js"></script> <script> goog.require('goog.dom'); </script> <script src="closure-library/closure/goog/dom.js"></script> <script> var newHeader = goog.dom.createDom('h1'); </script>
虽然在<script src="closure-library/closure/goog/dom.js"></script>
之前添加了var newHeader = goog.dom.createDom....
,但dom.js
将被下载,goog.dom.create....
完全在dom.js
之后执行下载并执行?但我听说js执行是异步的。我错过了什么吗?
答案 0 :(得分:1)
来自“使用入门”页面:
goog.require()调用添加了goog.dom.createDom()的代码 紧接在包含行var newHeader =的脚本标记之前 goog.dom.createDom( 'H1')。
脚本加载器通过将脚本元素插入DOM来加载脚本。它在“当前脚本元素”之后插入。这就是在使用动态加载脚本的函数之前需要“关闭”脚本元素的原因。
如果这是您的源html:
<script src="closure-library/closure/goog/base.js"></script>
<script>
goog.require('goog.dom');
</script>
<script>
var newHeader = goog.dom.createDom('h1');
</script>
解析器看到了这个:
<script src="closure-library/closure/goog/base.js"></script>
<script>
goog.require('goog.dom');
</script>
<script src="closure-library/closure/goog/dom.js"></script>
<script>
var newHeader = goog.dom.createDom('h1');
</script>
但如果您的来源是:
<script src="closure-library/closure/goog/base.js"></script>
<script>
goog.require('goog.dom');
var newHeader = goog.dom.createDom('h1');
</script>
解析器看到了这个:
<script src="closure-library/closure/goog/base.js"></script>
<script>
goog.require('goog.dom');
var newHeader = goog.dom.createDom('h1');
</script>
<script src="closure-library/closure/goog/dom.js"></script>
当然不起作用。
脚本执行是同步的。使用脚本元素下载脚本会阻止脚本的执行(以及页面的呈现)。这就是为什么你不应该将不必要的脚本元素放入<head>
。这将阻止解析器,从而阻止(a.k.a您的文档)之后的所有内容的呈现,直到下载脚本为止。
在HTML5中,script tags (async
)有一个属性,声明浏览器不应等待脚本下载。但默认行为是等待。