html注入中的jQuery脚本执行顺序

时间:2014-01-31 16:00:46

标签: javascript jquery html asynchronous

考虑以下JS代码:

var html = '<script>$("body").append("a");</script>'
         + '<script src="script.js"></script>'
         + '<script>$("body").append("c");</script>';

$("body").append(html);

并假设script.js包含以下内容:

$("body").append("b");

事实上,似乎“a”,“b”和“c”被附加到正文(按此顺序)。并且,显然,只有在script.js完成加载后才会将“c”附加到正文(例如,如果script.js需要5秒才能完成加载“c”将仅附加到正文5秒后)。

我的问题如下:我们可以依赖jQuery中的这种行为吗?它是确定性的还是我们可能遇到不可预测的情况?

这在动态加载使用尚未加载的.js文件的脚本方面很有用。您可以假设script.js实际上包含function f(){},第三行应该是<script>f()</script>。如果您将始终获得脚本加载/执行的相同顺序,则不会出现任何问题,否则您可能会遇到f is not defined异常(如果在加载script.js文件之前执行了标记)。

1 个答案:

答案 0 :(得分:4)

这不是jQuery特定的行为,而是浏览器行为。加载文档中预定义的脚本时,它们按顺序或外观加载。当您将脚本标记动态附加到文档时,情况并非如此。

如果你加载了你所展示的javascript文件,那么当DOM设置元素的来源时,它将开始下载外部文件。

实施例

Html文件头中的脚本

$(function() {
    var html = '<script>$("body").append("a");<\/script>' +
               '<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"><\/script>' +
               '<script>$("#my-dialog").dialog();<\/script>';

    $("body").append(html);
}

Html文件的正文元素

<div id="my-dialog">
    Some content here
</div>

上述代码无法按预期执行。 a将附加到正文,然后jQuery.ui将被加载,最后会出现dialog,但实际上第三个脚本会因为jQueryUI尚未完成下载而失败要解析。现在,如果您在控制台中键入$("#my-dialog").dialog();,则不会出现任何问题,因为此时下载并解析了文件。

这是模块加载器受欢迎的主要原因之一。您只需告诉它需要什么,它将按照所需的顺序为您加载它们。

您可以阅读有关脚本here的W3C规范的更多信息。