动态插入的脚本标记未按正确顺序执行

Xuf*_*eng 1 html javascript jquery

以下是我的HTML代码片段:

...

<script src=".../jquery.min.js"></script>

<script id="foo">
    if (!window.jQuery) {
        var jquery = document.createElement("script");
        jquery.src = ".../jquery.min.js";
        var self = document.getElementById("foo");
        self.parentNode.insertBefore(jquery, self.nextSibling);
        console.log("haha");
    }
</script>

<script>
    console.log("hehe");
</script>

<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

第一个脚本标记是jquery CDN.id为"foo"的脚本标记的目的是,如果CDN失败,它会在加载以下引导程序js文件之前加载jquery文件的本地副本.

但是,在bootstrap js文件之前不会以某种方式执行插入的jquery文件.我尝试console.log("wow")输入本地jquery文件.控制台的结果是"haha", "hehe", some error message from bootstrap js file, "wow".观察DOM,插入的jquery标记确实出现在"hehe"脚本之前,我想知道为什么它没有以正确的顺序执行,是否有更好的方法来实现我的目标?

jfr*_*d00 6

动态插入的脚本文件插入时document.write()不以任何可预测的顺序执行.它们是异步的,将按照自己的节奏加载和运行.

您不能依赖异步脚本相对于其他脚本的任何加载顺序,除非您编写代码来监视事情何时加载完毕并且仅在满足某些特定条件时运行代码.

如果您插入脚本document.write(),那么它将成为阻止脚本加载,它将在document.write()语句之后解析任何脚本标记之前加载并运行,就像<script>标记位于该点的页面源中一样.但是,使用document.write()某些浏览器加载优化时可能会出现混乱,因此使用该技术可能会有一些缺点.

你可以这样使用document.write():

<script src=".../jquery.min.js"></script>

<script>
    if (!window.jQuery) {
        document.write('<scr' + 'ipt src="../jquery.min.js"></scr' + 'ipt>');
    }
</script>
Run Code Online (Sandbox Code Playgroud)

关于此主题的整篇文章:CDN失败,但您的脚本不必 - 从CDN回退到本地jQuery.