如何强制动态插入的javascript文件继续执行?

时间:2016-09-21 19:52:22

标签: javascript jquery html asynchronous

我有一系列JavaScript库,它们保存在一个字符串中并传递给我的页面。我们正在加载一些第三方代码,并且它们具有我们必须放在页面上的多个功能,并且由于我们网站的性质,这些库中的某些库的数据在页面加载之后才可用(使用套接字。我将数据传递给我们。

这些"库中的一个例子"页面接收可能如下所示......

//"myId123" is generated on the page, sent to the server, and the server returns with the following two script tags as a single string
<script src="https://my.3rdparty.com/path/to/script.js"></script>
<script>
    myFunction({id:"myId123")
</script>

(它们作为一个字符串一起传递,然后使用jQuery将其解析为元素集合)

myFunction()从其上方的脚本标记加载(src = my.3rdparty.com /...)。

澄清一下,操作顺序如下......

  1. 请求页面
  2. 通过Jade生成的页面并发送到浏览器
  3. 浏览器加载页面
  4. 前端生成的会话变量,发送到服务器
  5. 在服务器上生成的动态库(使用来自前端的数据)
  6. 发送到前端的库
  7. 附加到页面的库
  8. 我的问题是,当我的外部脚本完成加载/执行,打破我的页面之前,myFunction()正在运行。

    如何强制第一个脚本标记在下一个脚本之前加载并执行?请注意,对于某些&#39;库,可能会颠倒顺序(即myFunction2()应在运行外部库之前运行,以便它可以生成外部库使用的变量)。我们可以假设它们在字符串中给我们的顺序是我们希望它们执行的顺序。

    更新。我正在插入我的图书馆&#39;使用以下功能......

    insertPixelLibs=function(libs){
        //libs is an array of these string-libraries
        for (var i=0;i<libs.length;i++){
            $('#libs_div').append($(libs[i]));
        }
    }
    

    使用$()将字符串转换为有效HTML元素的集合,它们似乎正在作为元素而不是文本正确追加。问题如上所述,其中未定义myFunction()。

1 个答案:

答案 0 :(得分:0)

我解决这个问题的方法是调用一个递归函数,逐个添加每个段。这是我的示例代码

function insertLibraries(libs){
    //libs is an array containing strings of valid HTML Element(s)
    var myLib ="";
    for (var i=0;i<libs.length;i++){
        myLib = $(libs[i]);
        insertLib(myLib,0);
    }
};
function insertLib(lib,i){
    //lib will be a string containing the library tag(s) to be inserted
    $lib = $(lib);//Convert to collection of jQuery elements
    if (typeof i != "number")i=0;
    if (i>=$lib.length) return;//if we added the last one in this library, return
    var myLib = $($lib[i]);
    if (myLib.prop('nodeType')===undefined) return insertLib(lib,++i);//continue to next iteration if it's just a text node between tags
    var newElm = document.createElement(myLib.prop('tagName'));//create a new element of the correct type
    var src = myLib.attr('src');
    if (src){
        newElm.src = src;
        //"onload" doesn't fire for local libraries, so we only put it on the external ones
        newElm.onload = function(){
            insertLib(lib,++i)//when this finishes loading, insert the next one in it's group
        };
        document.getElementById("my_div").appendChild(newElm);
    }
    else{
        var newHtml = $('<div>').html(myLib.html()).text();//this funky line basically decodes the html
        //meaning "1 &amp; 2" will turn into "1 & 2"
        newElm.innerHTML=newHtml;//currently only sets the HTML as text, not as a valid HTML child
        document.getElementById("my_div").appendChild(newElm);
        insertLib(lib,++i);
    }
};