如何包括使用jQuery $ .getScript多个js文件()方法(How to include

2019-06-17 14:53发布

我试图动态包括的javascript文件到我的js文件。 我做了一些关于它的研究,并找到jQuery的$ .getScript()方法将是一个希望的路要走。

// jQuery
$.getScript('/path/to/imported/script.js', function()
{
    // script is now loaded and executed.
    // put your dependent JS here.
    // what if the JS code is dependent on multiple JS files? 
});

但我想知道这种方法是否可以同时加载多个脚本? 为什么我问这是因为有时我的JavaScript文件取决于多个js文件。

先感谢您。

Answer 1:

答案是

您可以使用承诺getScript()并等待,直到所有的脚本加载,这样的:

$.when(
    $.getScript( "/mypath/myscript1.js" ),
    $.getScript( "/mypath/myscript2.js" ),
    $.getScript( "/mypath/myscript3.js" ),
    $.Deferred(function( deferred ){
        $( deferred.resolve );
    })
).done(function(){

    //place your code here, the scripts are all loaded

});

小提琴

ANOTHER FIDDLE

在上面的代码,增加了延迟和解决它里面$()是像放置任何其他函数一个jQuery呼叫内,如$(func)它是相同的如

$(function() { func(); });

也就是说,它等待DOM做好准备,所以在上面的例子中$.when被加载等待所有脚本 DOM来,因为的准备$.Deferred调用,它解决了DOM准备回调。


对于更通用的使用,方便的功能

接受可以这样被创建的脚本中的任意阵列效用函数:

$.getMultiScripts = function(arr, path) {
    var _arr = $.map(arr, function(scr) {
        return $.getScript( (path||"") + scr );
    });

    _arr.push($.Deferred(function( deferred ){
        $( deferred.resolve );
    }));

    return $.when.apply($, _arr);
}

这可以这样使用

var script_arr = [
    'myscript1.js', 
    'myscript2.js', 
    'myscript3.js'
];

$.getMultiScripts(script_arr, '/mypath/').done(function() {
    // all scripts loaded
});

其中,路径将被添加到所有的脚本,并且也是可选的,这意味着如果数组包含完整的URL的一个也可以做到这一点,并留下了路径一起

$.getMultiScripts(script_arr).done(function() { ...

参数,错误等。

顺便说一句,注意, done回调将包含多个匹配传入脚本,表示包含响应的阵列,每个参数的参数

$.getMultiScripts(script_arr).done(function(response1, response2, response3) { ...

其中每个阵列会包含类似[content_of_file_loaded, status, xhr_object] 我们一般不需要访问这些参数作为脚本会自动反正被加载,大部分的时间done回调都是我们真的知道后,所有的脚本已经加载,我只是将它完整性,以及当需要访问所加载文件的实际文本,或者当需要访问每个XHR对象或类似的东西罕见的情况下。

而且,如果所有的脚本加载失败,故障处理程序将被调用,并且后续的脚本不会被加载

$.getMultiScripts(script_arr).done(function() {
     // all done
}).fail(function(error) {
     // one or more scripts failed to load
}).always(function() {
     // always called, both on success and error
});


Answer 2:

我实现了一个简单的功能并行加载多个脚本:

功能

function getScripts(scripts, callback) {
    var progress = 0;
    scripts.forEach(function(script) { 
        $.getScript(script, function () {
            if (++progress == scripts.length) callback();
        }); 
    });
}

用法

getScripts(["script1.js", "script2.js"], function () {
    // do something...
});


Answer 3:

加载跟进所需的脚本在前面的一个类似的回调:

$.getScript('scripta.js', function()
{
   $.getScript('scriptb.js', function()
   {
       // run script that depends on scripta.js and scriptb.js
   });
});


Answer 4:

有时,需要以特定的顺序加载脚本。 例如jQuery的必须jQuery用户界面之前加载。 上并联(异步地)当前页加载脚本,这意味着执行顺序的大多数示例不被保证。 如果没有排序,脚本y取决于x ,如果两者都成功加载,可以打破,但在错误的顺序。

我提出了一个混合的做法,让相关脚本+可选并行装载+的顺序装载延迟对象 :

 /* * loads scripts one-by-one using recursion * returns jQuery.Deferred */ function loadScripts(scripts) { var deferred = jQuery.Deferred(); function loadScript(i) { if (i < scripts.length) { jQuery.ajax({ url: scripts[i], dataType: "script", cache: true, success: function() { loadScript(i + 1); } }); } else { deferred.resolve(); } } loadScript(0); return deferred; } /* * example using serial and parallel download together */ // queue #1 - jquery ui and jquery ui i18n files var d1 = loadScripts([ "https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/jquery-ui.min.js", "https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.1/i18n/jquery-ui-i18n.min.js" ]).done(function() { jQuery("#datepicker1").datepicker(jQuery.datepicker.regional.fr); }); // queue #2 - jquery cycle2 plugin and tile effect plugin var d2 = loadScripts([ "https://cdn.rawgit.com/malsup/cycle2/2.1.6/build/jquery.cycle2.min.js", "https://cdn.rawgit.com/malsup/cycle2/2.1.6/build/plugin/jquery.cycle2.tile.min.js" ]).done(function() { jQuery("#slideshow1").cycle({ fx: "tileBlind", log: false }); }); // trigger a callback when all queues are complete jQuery.when(d1, d2).done(function() { console.log("All scripts loaded"); }); 
 @import url("https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/blitzer/jquery-ui.min.css"); #slideshow1 { position: relative; z-index: 1; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <p><input id="datepicker1"></p> <div id="slideshow1"> <img src="https://dummyimage.com/300x100/FC0/000"> <img src="https://dummyimage.com/300x100/0CF/000"> <img src="https://dummyimage.com/300x100/CF0/000"> </div> 

在两个队列中的脚本将并行下载,然而,在每个队列中的脚本将下载顺序,确保有序执行。 瀑布图:



Answer 5:

使用yepnope.js或Modernizr的 (包括作为yepnope.js Modernizr.load )。

UPDATE

只需跟进,这里就是你当前使用什么yepnope,表现出对多个脚本依赖关系的良好相当于:

yepnope({
  load: ['script1.js', 'script2.js', 'script3.js'],
  complete: function () {
      // all the scripts have loaded, do whatever you want here
  }
});


Answer 6:

我遇到了许多问题具有多脚本加载inculding一个问题有(至少在Chrome)阿贾克斯被成功加载其中的跨域工作完全正常后,没有实际运行脚本的同一个域加载热! :(

所选择的答案,原来的问题不正常。

很多很多次迭代后,这里是我最后的答案getScript加入(S)和特定严格的顺序,每个脚本加载回调选项,并在完成整体回调异步加载多个脚本,测试jQuery的2.1+和Chrome,火狐加上现代版本抛弃IE浏览器。

我的测试案件被加载了three.js所WebGL的渲染文件,然后启动渲染脚本时,全球三大变得可使用传递给一个匿名函数调用的onComplete的间隔检查。

原型函数(getScripts)

function getScripts( scripts, onScript, onComplete )
{
    this.async = true;
    this.cache = false;
    this.data = null;
    this.complete = function () { $.scriptHandler.loaded(); };
    this.scripts = scripts;
    this.onScript = onScript;
    this.onComplete = onComplete;
    this.total = scripts.length;
    this.progress = 0;
};

getScripts.prototype.fetch = function() {
    $.scriptHandler = this;
    var src = this.scripts[ this.progress ];
    console.log('%cFetching %s','color:#ffbc2e;', src);

    $.ajax({
        crossDomain:true,
        async:this.async,
        cache:this.cache,
        type:'GET',
        url: src,
        data:this.data,
        statusCode: {
            200: this.complete
        },
        dataType:'script'
    });
};

getScripts.prototype.loaded = function () {
    this.progress++;
    if( this.progress >= this.total ) {
        if(this.onComplete) this.onComplete();
    } else {
        this.fetch();
    };
    if(this.onScript) this.onScript();
};

如何使用

var scripts = new getScripts(
    ['script1.js','script2.js','script.js'],
    function() {
        /* Optional - Executed each time a script has loaded (Use for Progress updates?) */
    },
    function () {
        /* Optional - Executed when the entire list of scripts has been loaded */
    }
);
scripts.fetch();

该功能是因为它是我发现使用延迟(现在已经过时?),当,成功和完成我的试验,以不是100%可靠!?,因此这个功能,例如使用的StatusCode的。

您可能需要添加错误/故障处理的行为,如果你的愿望。



Answer 7:

你可以利用的$.when试图通过下面的函数-方法:

function loadScripts(scripts) {
  scripts.forEach(function (item, i) {
    item = $.getScript(item);
  });
  return $.when.apply($, scripts);
}

该功能将使用这样的:

loadScripts(['path/to/script-a.js', 'path/to/script-b.js']).done(function (respA, respB) {
    // both scripts are loaded; do something funny
});

这是使用的承诺,并有一个最小的开销的方式。



Answer 8:

伟大的答案,adeneo。

我花了一些时间来弄清楚如何使你的答案更通用的(这样我就可以加载的代码定义的脚本的数组)。 当所有的脚本都加载并执行回调函数被调用。 这里是我的解决方案:

    function loadMultipleScripts(scripts, callback){
        var array = [];

        scripts.forEach(function(script){
            array.push($.getScript( script ))
        });

        array.push($.Deferred(function( deferred ){
                    $( deferred.resolve );
                }));

        $.when.apply($, array).done(function(){
                if (callback){
                    callback();
                }
            });
    }


Answer 9:

你要找的是AMD兼容装载机(如require.js)。

http://requirejs.org/

http://requirejs.org/docs/whyamd.html

有很多优秀的开源的,如果你看看它。 基本上,这允许您定义的代码模块,如果它是依赖于其它代码的模块,它会等到这些模块已经完成在继续运行之前下载。 这样,您就可以异步加载10个模块,并且即使一个依赖于几个人的运行应该没有问题。



Answer 10:

此功能将确保依赖文件完全加载后一个文件被加载。 你只需要提供牢记上的其他文件的依赖序列的文件。

function loadFiles(files, fn) {
    if (!files.length) {
        files = [];
    }
    var head = document.head || document.getElementsByTagName('head')[0];

    function loadFile(index) {
        if (files.length > index) {
            var fileref = document.createElement('script');
            fileref.setAttribute("type", "text/javascript");
            fileref.setAttribute("src", files[index]);
            head.appendChild(fileref);
            index = index + 1;
            // Used to call a callback function
            fileref.onload = function () {
                loadFile(index);
            }
        } else if(fn){
            fn();
        }
    }
    loadFile(0);
}


Answer 11:

这对我的作品:

function getScripts(scripts) {
    var prArr = [];
    scripts.forEach(function(script) { 
        (function(script){
            prArr .push(new Promise(function(resolve){
                $.getScript(script, function () {
                    resolve();
                });
            }));
        })(script);
    });
    return Promise.all(prArr, function(){
        return true;
    });
}

并使用它:

var jsarr = ['script1.js','script2.js'];
getScripts(jsarr).then(function(){
...
});


Answer 12:

下面是使用马切伊Sawicki的一个贯彻答案Promise回调:

function loadScripts(urls, path) {
    return new Promise(function(resolve) {
        urls.forEach(function(src, i) {

            let script = document.createElement('script');        
            script.type = 'text/javascript';
            script.src = (path || "") + src;
            script.async = false;

            // If last script, bind the callback event to resolve
            if(i == urls.length-1) {                    
                // Multiple binding for browser compatibility
                script.onreadystatechange = resolve;
                script.onload = resolve;
            }

            // Fire the loading
            document.body.appendChild(script);
        });
    });
}

使用:

let JSDependencies = ["jquery.js",
                      "LibraryNeedingJquery.js",
                      "ParametersNeedingLibrary.js"];

loadScripts(JSDependencies,'JavaScript/').then(taskNeedingParameters);

所有的JavaScript文件尽快下载并执行给定的顺序。 然后taskNeedingParameters被调用。



Answer 13:

较短的版本安德鲁·马克·牛顿以上全面的答案。 这其中不检查成功,你应该做,以避免不确定的UI行为的状态代码。

这一次是为一个恼人的系统,在那里我可以保证jQuery的,但没有其他的包括,所以我想一个技术很短,不关养殖到外部脚本如果强行进去。 (你可以使它更短的索引0传递到第一个“递归”呼叫,但风格习惯的力量让我加了糖)。

我还指定依赖列表中的模块名称,所以这个块可以在任何地方被列入需要“模块1”和脚本和相关的初始化将只包含/运行一次(你可以登录index回调,看到一个单一有序集合AJAX请求的捉迷藏)

if(typeof(__loaders) == 'undefined') __loaders = {};

if(typeof(__loaders.module1) == 'undefined')
{
    __loaders.module1 = false;

    var dependencies = [];

    dependencies.push('/scripts/loadmefirst.js');
    dependencies.push('/scripts/loadmenext.js');
    dependencies.push('/scripts/loadmelast.js');

    var getScriptChain  = function(chain, index)        
    {
        if(typeof(index) == 'undefined')
            index = 0;

        $.getScript(chain[index], 
            function()
            {
                if(index == chain.length - 1)
                {
                    __loaders.module1 = true;

                    /* !!!
                        Do your initialization of dependent stuff here 
                    !!! */
                }
                else 
                    getScriptChain(chain, index + 1);
            }
        );
    };

    getScriptChain(dependencies);       
}


Answer 14:

有一个插件,在那里,扩展jQuery的getScript加入方法。 允许异步和同步加载和使用jQuery的缓存机制。 充分披露,我写了这一点。 如果你找到一个更好的方法请随时作出贡献。

https://github.com/hudsonfoo/jquery-getscripts



Answer 15:

负载ñ脚本逐个(例如,如果第二个文件需要一日一有用):

(function self(a,cb,i){
    i = i || 0; 
    cb = cb || function(){};    
    if(i==a.length)return cb();
    $.getScript(a[i++],self.bind(0,a,cb,i));                    
})(['list','of','script','urls'],function(){console.log('done')});


Answer 16:

基于回答@adeneo以上:结合的CSS和JS文件都加载

任何改进的建议?

// Usage
//$.getMultiResources(['script-1.js','style-1.css'], 'assets/somePath/')
//  .done(function () {})
//  .fail(function (error) {})
//  .always(function () {});

(function ($) {
  $.getMultiResources = function (arr, pathOptional, cache) {
    cache = (typeof cache === 'undefined') ? true : cache;
    var _arr = $.map(arr, function (src) {
      var srcpath = (pathOptional || '') + src;
      if (/.css$/i.test(srcpath)) {
        return $.ajax({
          type: 'GET',
          url: srcpath,
          dataType: 'text',
          cache: cache,
          success: function () {
            $('<link>', {
              rel: 'stylesheet',
              type: 'text/css',
              'href': srcpath
            }).appendTo('head');
          }
        });

      } else {
        return $.ajax({
          type: 'GET',
          url: srcpath,
          dataType: 'script',
          cache: cache
        });
      }
    });
    //
    _arr.push($.Deferred(function (deferred) {
      $(deferred.resolve);
    }));
    //
    return $.when.apply($, _arr);
  };
})(jQuery);


Answer 17:

追加脚本与异步=假

这里有一个不同,但超级简单的方法。 要加载多个脚本可以将它们简单地追加到身体。

  • 加载它们异步执行,因为这是浏览器如何优化页面加载
  • 执行脚本为了,因为这是浏览器如何解析HTML标签
  • 无需回调,因为脚本是按顺序执行。 只需添加另一个脚本,它会在其他脚本后执行

更多资讯: https://www.html5rocks.com/en/tutorials/speed/script-loading/

var scriptsToLoad = [
   "script1.js", 
   "script2.js",
   "script3.js",
]; 

scriptsToLoad.forEach(function(src) {
  var script = document.createElement('script');
  script.src = src;
  script.async = false;
  document.body.appendChild(script);
});


文章来源: How to include multiple js files using jQuery $.getScript() method