Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
动态包含JavaScript并等待_Javascript_Ajax - Fatal编程技术网

动态包含JavaScript并等待

动态包含JavaScript并等待,javascript,ajax,Javascript,Ajax,我试图做的是在Javascript中动态地包含一个或多个js文件。我知道有很多方法可以做到这一点,但我正在寻找一种遵循以下规则的解决方案: 1) 不使用任何JS框架或库(jQuery、Prototype等) 2) 脚本应该停止执行,直到外部js文件被浏览器完全加载和解析 rational behind#2是外部js文件,它将包含在脚本包含之后需要立即使用的函数定义。在我开始调用这些函数之前,浏览器大部分时间都没有时间解析js文件 我不介意使用回调来知道脚本何时完成加载,但是: 1) 我不知道提前

我试图做的是在Javascript中动态地包含一个或多个js文件。我知道有很多方法可以做到这一点,但我正在寻找一种遵循以下规则的解决方案:

1) 不使用任何JS框架或库(jQuery、Prototype等)

2) 脚本应该停止执行,直到外部js文件被浏览器完全加载和解析

rational behind#2是外部js文件,它将包含在脚本包含之后需要立即使用的函数定义。在我开始调用这些函数之前,浏览器大部分时间都没有时间解析js文件

我不介意使用回调来知道脚本何时完成加载,但是:

1) 我不知道提前动态包含多少脚本,所以我不想也不能编写一堆嵌套回调。我只想知道他们什么时候都装好了

2) 我认为,如果浏览器缓存了JavaScript,那么尝试使用某种“加载”事件来触发回调可能不起作用

编辑我应该从一开始就提到这是一个插件系统,但我想让我的问题/答案足够通用,以便对其他人有所帮助

用户将定义要在阵列中加载的插件

plugins = [ 'FooPlugin', 'BarPlugin' ];
然后,我将在数组中循环,并为每个插件加载js脚本:

for(var i = 0; i < plugins.length; i++) {
    loadScript('plugins/' + plugins[i] + '.js');
}
我所知道的最简单(也是最可靠)的解决方案就是简单地使用document.write在文档中插入一个新的脚本标记(当然,也可以根据您的需要):


我脑子里有几种可能的方法。我要写的是步骤,不是代码

选项1

  • 通过将JS文件放置在带有标记的元素中来加载它
  • 就在触发setTimout()之后,检查加载的JS文件中是否有变量
  • 重复#2,直到变量存在或到达maxCounter(maxCounter=10),这样您就不会永远坐在那里了
  • 变量存在后,继续下一个JS文件并再次从步骤1开始
  • 选项2

  • 使用Ajax方法
  • 使用Ajax调用JS文件
  • 将结果附加到下面文章中的使用说明中
  • 将setTimeout()函数设置为几秒钟,处理脚本或检查类似于选项#1的变量,并重复超时,直到变量出现
  • 两种方法均参考本文:

    困难的部分是,您要求您的代码知道浏览器何时加载和处理每个JS文件。由于计算机和浏览器的不同,处理JS文件所需的时间也会有所不同,如果JS文件中没有一些逻辑,则很难进行跟踪

    我更喜欢这样的方法:

    1。为能够处理动态逻辑的服务器(php、java、.NET等)创建Javascript请求标记、ajax等

    2。传递一个回调函数,该函数已经存在于页面上,并且知道需要知道多少额外的JS文件。甚至在回调中包含一个索引参数(类似于myCallback(5)),这样您就知道自己在哪里了

    1-2a。您可以手动将回调函数附加到所有JS文件中,让该函数管理JS队列,而JS文件除了回调函数之外没有任何其他知识

    3。让服务器将回调附加到返回的JS文件中

    4。一旦JS被处理,回调函数将被触发,它将为您管理额外JS文件的加载


    怎么样?

    可以跨浏览器工作,从IE6开始

    document.loadScript = function (src, callback) {
        function script(src, onload) {
            var scriptTag = document.createElement('script');
            if (onload) scriptTag.onload = onload;
            scriptTag.src = src;
            scriptTag.type = 'text/javascript';
            return scriptTag;
        }
        function outer(tag) { 
            var d = document.createElement('div');
            d.appendChild(tag);
            return d.innerHTML;
        }
        if (!(src instanceof Array)) src = [src];
        var i, scr, 
            callbackId = 'dynCall_'+Math.floor(Math.random()*89999+10000);
            counter = src.length, 
            call = function () { if (--counter == 0) callback(); };
        if (!document.body) {
            window[callbackId] = function () {
                delete window[callbackId];
                if (callback instanceof Function) callback();
            };
            for (i=0; i<src.length; i++) document.write(outer(script(src[i])));
            document.write('<scr'+'ipt type="text/javascript">'+'window.'+callbackId+'();'+'</scr'+'ipt>');
            return;
        }
        for (i=0; i<src.length; i++) document.body.appendChild(script(src[i], call));
    };
    
    document.loadScript=函数(src,回调){
    函数脚本(src,onload){
    var scriptTag=document.createElement('script');
    如果(onload)scriptTag.onload=onload;
    scriptTag.src=src;
    scriptTag.type='text/javascript';
    返回脚本标签;
    }
    函数外部(标记){
    var d=document.createElement('div');
    d、 附加子(tag);
    返回d.innerHTML;
    }
    如果(!(src instanceof Array))src=[src];
    变量i,scr,
    callbackId='dynCall_u'+Math.floor(Math.random()*89999+10000);
    计数器=src.length,
    call=function(){if(--counter==0)callback();};
    如果(!document.body){
    窗口[callbackId]=函数(){
    删除窗口[callbackId];
    if(callback instanceof Function)callback();
    };
    
    对于(i=0;idocument.write只是初始页面加载期间的一个可行解决方案。之后任何时候使用它都会覆盖整个页面。问题比这更复杂。解释了动态加载javascript,但这还不够聪明,无法实现脚本何时完成执行。是的,很好;我只有我们两个很久以前,我就在脑海中直接提到了这一点。第二种方法是跨浏览器兼容的?是的,是的。这也是一种很好的模块化方法。我不确定这个答案,所以就把它作为一个注释发布。您是否试过使用AJAX将javascript的内容加载到客户端变量中,然后使用
    eval()
    ?由于您必须等待AJAX返回200/OK消息,因此您知道整个脚本都已加载,
    eval()
    在完成整个脚本的运行之前,不应将您踢到下一行。您能确定页面加载期间需要哪些脚本吗?如果是,那么@Paul的解决方案是理想的。否则,您的解决方案将取决于您要支持的浏览器以及脚本是否与您的页面位于同一域中。@steven_desu-不会加载的脚本中的函数/变量最终会在调用eval()的上下文中结束?这意味着它们在使用eval的函数之外不可用。需要明确的是…是scr。
    <script type="text/javascript">document.write('<' + 'script src="/assets/js/file.js" type="text/javascript"><\/script>');</script>
    
    Loader.script( [
        './js/jquery/jquery.jmap.js',
        './js/jquery/jquery.getUrlParam.js',
        './js/jquery/jquery.form.js',
        './js/jquery/jquery.gettext.js',
        './js/jquery/jquery.scrollTo.js',
        './js/jquery/jquery.prettydate.js'
      ], { complete: function() {
        // do your thing
      }
    })
    
    document.loadScript = function (src, callback) {
        function script(src, onload) {
            var scriptTag = document.createElement('script');
            if (onload) scriptTag.onload = onload;
            scriptTag.src = src;
            scriptTag.type = 'text/javascript';
            return scriptTag;
        }
        function outer(tag) { 
            var d = document.createElement('div');
            d.appendChild(tag);
            return d.innerHTML;
        }
        if (!(src instanceof Array)) src = [src];
        var i, scr, 
            callbackId = 'dynCall_'+Math.floor(Math.random()*89999+10000);
            counter = src.length, 
            call = function () { if (--counter == 0) callback(); };
        if (!document.body) {
            window[callbackId] = function () {
                delete window[callbackId];
                if (callback instanceof Function) callback();
            };
            for (i=0; i<src.length; i++) document.write(outer(script(src[i])));
            document.write('<scr'+'ipt type="text/javascript">'+'window.'+callbackId+'();'+'</scr'+'ipt>');
            return;
        }
        for (i=0; i<src.length; i++) document.body.appendChild(script(src[i], call));
    };
    
    (function(){document.loadScript=function(src,callback){function script(src,onload){var scriptTag=document.createElement('script');if(onload)scriptTag.onload=onload;scriptTag.src=src;scriptTag.type='text/javascript';return scriptTag}function outer(tag){var d=document.createElement('div');d.appendChild(tag);return d.innerHTML}if(!(src instanceof Array))src=[src];var i,scr,callbackId='dynCall_'+Math.floor(Math.random()*89999+10000);counter=src.length,call=function(){if(--counter==0)callback()};if(!document.body){window[callbackId]=function(){delete window[callbackId];if(callback instanceof Function)callback()};for(i=0;i<src.length;i++)document.write(outer(script(src[i])));document.write('<scr'+'ipt type="text/javascript">'+'window.'+callbackId+'();'+'</scr'+'ipt>');return}for(i=0;i<src.length;i++)document.body.appendChild(script(src[i],call))};document.loadScript.toString=function(){return'function loadScript() { [obfuscated] }'}})();