我有一些<script>元素,其中一些代码依赖于其他<script>元素中的代码。我看到defer属性在这里可以派上用场,因为它允许延迟代码块的执行。

为了测试它,我在Chrome上执行了这个:http://jsfiddle.net/xXZMN/。

<script defer="defer">alert(2);</script>
<script>alert(1)</script>
<script defer="defer">alert(3);</script>

然而,它提醒2 - 1 - 3。为什么它不提醒1 - 2 - 3?


当前回答

HTML5规范中的一些片段:http://w3c.github.io/html/semantics-scripting.html#element-attrdef-script-async

必须使用defer和async属性 如果SRC属性没有被指定 不存在。


There are three possible modes that can be selected using these attributes [async and defer]. If the async attribute is present, then the script will be executed asynchronously, as soon as it is available. If the async attribute is not present but the defer attribute is present, then the script is executed when the page has finished parsing. If neither attribute is present, then the script is fetched and executed immediately, before the user agent continues parsing the page.


The exact processing details for these attributes are, for mostly historical reasons, somewhat non-trivial, involving a number of aspects of HTML. The implementation requirements are therefore by necessity scattered throughout the specification. The algorithms below (in this section) describe the core of this processing, but these algorithms reference and are referenced by the parsing rules for script start and end tags in HTML, in foreign content, and in XML, the rules for the document.write() method, the handling of scripting, etc.


如果元素有src属性, 元素有一个defer属性, 元素被标记为 "parser-inserted"和元素 没有async属性: 元素必须添加到脚本列表的末尾 当文档完成时执行 与文档相关的解析 对象的解析器的 元素。

其他回答

还应该注意的是,在IE<=9中,在某些情况下使用脚本延迟可能会出现问题。更多相关信息:https://github.com/h5bp/lazyweb-requests/issues/42

HTML5规范中的一些片段:http://w3c.github.io/html/semantics-scripting.html#element-attrdef-script-async

必须使用defer和async属性 如果SRC属性没有被指定 不存在。


There are three possible modes that can be selected using these attributes [async and defer]. If the async attribute is present, then the script will be executed asynchronously, as soon as it is available. If the async attribute is not present but the defer attribute is present, then the script is executed when the page has finished parsing. If neither attribute is present, then the script is fetched and executed immediately, before the user agent continues parsing the page.


The exact processing details for these attributes are, for mostly historical reasons, somewhat non-trivial, involving a number of aspects of HTML. The implementation requirements are therefore by necessity scattered throughout the specification. The algorithms below (in this section) describe the core of this processing, but these algorithms reference and are referenced by the parsing rules for script start and end tags in HTML, in foreign content, and in XML, the rules for the document.write() method, the handling of scripting, etc.


如果元素有src属性, 元素有一个defer属性, 元素被标记为 "parser-inserted"和元素 没有async属性: 元素必须添加到脚本列表的末尾 当文档完成时执行 与文档相关的解析 对象的解析器的 元素。

因为defer属性只适用于带有src的脚本标签。找到了一种方法来模拟内联脚本的延迟。使用DOMContentLoaded事件。

<script defer src="external-script.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function(event) {
    // Your inline scripts which uses methods from external-scripts.
});
</script>

这是因为,DOMContentLoaded事件在延迟带属性脚本完全加载后触发。

<脚本延迟> - 只要浏览器使用defer与脚本标记进行交互

它开始获取脚本文件,同时还并排解析HTML。 在这种情况下,脚本只在HTML解析完成后执行。

<脚本async> - 当浏览器与async交互脚本标记时

它在并排解析HTML时开始获取脚本文件。 但是在完全获取脚本时停止HTML解析,然后开始执行脚本,之后继续进行HTML解析。

<脚本> - - - 只要浏览器与脚本标记交互

它停止HTML的解析,获取脚本文件, 在本例中,执行脚本,然后继续解析HTML。

defer属性是一个布尔属性。

当出现时,它指定当页面完成解析时执行脚本。

注意:defer属性仅用于外部脚本(应该仅在src属性存在时使用)。

注意:有几种方式可以执行外部脚本:

如果出现async:脚本将与页面的其余部分异步执行(在页面继续解析时将执行脚本) 如果async不存在,而defer存在:当页面完成解析时执行脚本 如果async和defer都不存在:在浏览器继续解析页面之前,立即获取并执行脚本