Javascript 确切地说,<;脚本延迟=";“推迟”&燃气轮机;工作

Javascript 确切地说,<;脚本延迟=";“推迟”&燃气轮机;工作,javascript,html,deferred-execution,Javascript,Html,Deferred Execution,我有几个元素,其中一些元素中的代码依赖于其他元素中的代码。我看到defer属性在这里很有用,因为它允许代码块在执行时被延迟 为了测试它,我在Chrome上执行了以下命令: 警报(2); 警报(1) 警惕(3); 但是,它会提醒2-1-3。为什么它不发出警报1-2-3?更新日期:2016年2月19日 认为这个答案过时了。有关更新浏览器版本的信息,请参阅本文的其他答案 基本上,defer告诉浏览器在该脚本块中执行javascript之前等待“直到准备就绪”。通常这是在DOM完成加载并且docum

我有几个
元素,其中一些元素中的代码依赖于其他
元素中的代码。我看到
defer
属性在这里很有用,因为它允许代码块在执行时被延迟

为了测试它,我在Chrome上执行了以下命令:

警报(2);
警报(1)
警惕(3);
但是,它会提醒
2-1-3
。为什么它不发出警报
1-2-3

更新日期:2016年2月19日 认为这个答案过时了。有关更新浏览器版本的信息,请参阅本文的其他答案


基本上,defer告诉浏览器在该脚本块中执行javascript之前等待“直到准备就绪”。通常这是在DOM完成加载并且document.readyState==4之后

“延迟”属性特定于internet explorer。在InternetExplorer8中,在Windows7中,我在JSFiddle测试页面中看到的结果是,1-2-3

结果可能因浏览器而异

与流行的信念相反,IE遵循标准的频率比人们所说的要高,实际上“延迟”属性是在DOM级别1规范中定义的

W3C对延迟的定义:


“设置后,此布尔属性向用户代理提供提示,说明脚本不会生成任何文档内容(例如,javascript中没有“document.write”),因此,用户代理可以继续解析和呈现。”

HTML5规范中的一些片段:

延迟和异步属性必须是 如果src属性 他不在场


有三种可能的模式 可以使用以下选项进行选择: 属性[异步和延迟]。如果异步属性为 如果存在,则脚本将被删除 异步执行,只要 有空。如果异步属性 不存在,但存在defer属性 如果存在,则脚本为 当页面完成时执行 解析。如果两个属性都不是 如果存在,则获取脚本 并在审判前立即执行 用户代理继续解析页面


具体的处理细节 这些属性主要是历史属性 原因有点不足为奇, 涉及HTML的许多方面。 实施要求如下: 因此必然分散 在整个规范中。这个 下面的算法(在本节中) 描述此处理的核心, 但这些算法都是有参考价值的 由的分析规则引用 在HTML中为开始和结束标记编写脚本 外来内容和XML中的规则 对于document.write()方法 处理脚本等


如果元素具有src属性, 元素有一个defer属性, 并且该元素已标记为 “插入解析器”,以及元素 没有异步属性:

必须将元素添加到将要创建的脚本列表的末尾 文档完成后执行 与文档关联的解析 创建 元素


真正的答案是:因为你不能信任别人

在概念上,延迟和异步的区别如下:

async允许在后台下载脚本而无需阻塞。然后,当它完成下载时,渲染将被阻止,脚本将执行。执行脚本后,渲染将继续

defer做同样的事情,只是声明保证脚本按照页面上指定的顺序执行,并且在文档完成解析后执行。因此,一些脚本可能会完成下载,然后坐在那里等待稍后下载但出现在它们面前的脚本

不幸的是,由于这是一场真正的标准大战,defer的定义因规范而异,甚至在最新的规范中也没有提供有用的保证。正如回答和演示的那样,浏览器实现延迟的方式不同:

  • 在某些情况下,某些浏览器存在导致
    defer
    脚本无序运行的错误
  • 有些浏览器将
    DOMContentLoaded
    事件延迟到
    defer
    脚本加载之后,有些浏览器则没有
  • 有些浏览器在
    元素上使用内联代码,但不使用
    src
    属性,而遵从
    defer
    ,有些浏览器则忽略它
幸运的是,规范至少指定了异步覆盖延迟。因此,您可以将所有脚本视为异步脚本,并获得广泛的浏览器支持,如下所示:

<script defer async src="..."></script>

全球98%的浏览器和美国99%的浏览器将通过这种方法避免阻塞


(如果您需要等待文档完成解析,请收听事件
DOMContentLoaded
事件,或者使用jQuery的便捷
.ready()
函数。无论如何,您都希望这样做,以便在根本不实现
defer
的浏览器上优雅地返回。)

此布尔属性设置为向浏览器指示脚本将在解析文档后执行。由于此功能尚未在所有其他主流浏览器中实现,因此作者不应假定脚本的执行实际上会延迟。永远不要从延迟脚本调用document.write()(因为Gecko 1.9.2,这将吹走文档)。对于没有src属性的脚本,不应使用defer属性。自Gecko 1.9.2以来,对于没有src属性的脚本,会忽略defer属性。但是,在Gecko 1.9.1中,如果设置了defer属性,则即使内联脚本也会延迟

defer适用于chrome、firefox、ie>7和Safari


ref:

延迟属性仅用于外部脚本(仅当存在src属性时才应使用)。

还应注意,IE中可能存在问题
<script defer async src="..."></script>
<script defer src="external-script.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function(event) {
    // Your inline scripts which uses methods from external-scripts.
});
</script>
<script src="//other-domain.com/1.js" defer></script>
<script src="2.js" defer></script>