Javascript,按顺序执行脚本代码插入dom树

标签 javascript

不是重复的,因为我还没有在其他线程上找到令人满意的答案:


请寻找原生 Javascript 答案,没有 jQuery,没有 requireJS,等等 :)


整个问题的总结:

我想异步加载脚本但是已经有序执行

我试图强制插入的脚本元素中的代码完全按照添加到 dom 树的相同顺序执行。

也就是说,如果我插入两个脚本标签,第一个和第二个,第一个中的任何代码都必须在第二个之前触发,无论谁先完成加载。

我在插入头部时尝试使用 async 属性和 defer 属性,但似乎不服从。

我尝试过 element.setAttribute("defer", "") 和 element.setAttribute("async", false) 以及其他组合。

我目前遇到的问题是在包含外部脚本时必须解决的问题,但这也是我在存在延迟的情况下执行的唯一测试。

第二个脚本是本地脚本,总是在第一个脚本之前触发,即使它是在之后插入到 dom 树 ( head ) 中的。

A) 请注意 我仍在尝试将两个脚本元素插入到 DOM 中。当然上面可以通过先插入来实现,让它完成并插入第二个,但我希望有另一种方法,因为这可能很慢。

我的理解是 RequireJS 似乎就是在做这个,所以应该是可以的。然而,requireJS 可能会按照 A 中的描述完成它。

如果您想直接在 firebug 中尝试代码,只需复制并粘贴:

    function loadScript(path, callback, errorCallback, options) {
            var element = document.createElement('script');
            element.setAttribute("type", 'text/javascript');
            element.setAttribute("src", path);

            return loadElement(element, callback, errorCallback, options);
    }

    function loadElement(element, callback, errorCallback, options) {
            element.setAttribute("defer", "");
            // element.setAttribute("async", "false");

            element.loaded = false;

            if (element.readyState){  // IE
                    element.onreadystatechange = function(){
                            if (element.readyState == "loaded" || element.readyState == "complete"){
                                    element.onreadystatechange = null;

                                    loadElementOnLoad(element, callback);
                            }
                    };
            } else {                 // Others
                    element.onload = function() {
                            loadElementOnLoad(element, callback);
                    };
            }

            element.onerror = function() {
                    errorCallback && errorCallback(element);
            };

            (document.head || document.getElementsByTagName('head')[0] || document.body).appendChild(element);

            return element;
    }

    function loadElementOnLoad(element, callback) {
            if (element.loaded != true) {
                    element.loaded = true;
                    if ( callback ) callback(element);
            }
    }




loadScript("http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js",function() {
  alert(1);  
})

loadScript("http://ajax.googleapis.com/ajax/libs/chrome-frame/1.0.3/CFInstall.min.js",function() {
  alert(2);  
})

如果你像 Firebug 一样尝试上面的代码,它通常会触发 2,然后是 1。我想确保先是 1,然后是 2,但两者都包含在头部。

最佳答案

if I insert two script tags, first and second, any code in first must fire before the second, no matter who finishes loading first. I have tried with the async attribute and defer attribute

不,asyncdefer 在这里帮不了你。每当您将脚本元素动态插入 DOM 时,它们都会异步加载和执行。你对此无能为力。

My understanding is that RequireJS seems to be doing just this

没有。即使使用 RequireJS,脚本也是异步执行的,而不是按顺序执行的。只有那些脚本中的模块初始化函数只是define()d,没有被执行。然后,Requirejs 确实会在满足它们的依赖关系时进行查找,并在稍后加载其他模块时执行它们。

当然你可以重新发明轮子,但你必须使用类似 requirejs 的结构。

关于Javascript,按顺序执行脚本代码插入dom树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17978255/

相关文章:

javascript - 如何在 asp.net 中更改鼠标悬停时的标签文本

javascript - 正确显示逗号

javascript - Stripe 支付流程

JavaScript 从列表中删除元素

javascript - 将背景图片 url 分配给模板中的 div

javascript - 仅在点击的 div 上运行脚本

javascript - 如何使用包含属性名称的变量检查对象属性是否存在?

javascript - 用JS检测后退和前进按钮

javascript - 如何从数组中拆分和搜索?

c# - 使用 JavaScript 获取选中的 RadioButtons