如何使用jQuery $ .getScript()方法包含多个js文件

soz*_*hen 120 html javascript jquery promise

我试图动态地将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? 
});
Run Code Online (Sandbox Code Playgroud)

但我想知道这种方法是否可以一次加载多个脚本?为什么我问这是因为有时我的javascript文件依赖于多个js文件.

先感谢您.

ade*_*neo 301

答案是

您可以使用promises 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

});
Run Code Online (Sandbox Code Playgroud)

小提琴

ANOTHER FIDDLE

在上面的代码中,添加一个Deferred并将其解析为内部$()就像在jQuery调用中放置任何其他函数一样$(func),就像它一样

$(function() { func(); });
Run Code Online (Sandbox Code Playgroud)

即它等待DOM准备就绪,因此在上面的例子中$.when等待加载所有脚本并且由于$.Deferred在DOM就绪回调中解析的调用而使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);
}
Run Code Online (Sandbox Code Playgroud)

可以像这样使用

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

$.getMultiScripts(script_arr, '/mypath/').done(function() {
    // all scripts loaded
});
Run Code Online (Sandbox Code Playgroud)

路径将被添加到所有脚本的位置,并且也是可选的,这意味着如果数组包含完整的URL,那么也可以执行此操作,并将所有路径全部放在一起

$.getMultiScripts(script_arr).done(function() { ...
Run Code Online (Sandbox Code Playgroud)

争论,错误等

另外,请注意done回调将包含许多与传入脚本匹配的参数,每个参数表示包含响应的数组

$.getMultiScripts(script_arr).done(function(response1, response2, response3) { ...
Run Code Online (Sandbox Code Playgroud)

每个数组都包含类似的内容[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
});
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的回答.你能不能解释一下为什么在这里添加`$ .Deferred(function(deferred){$(deferred.resolve);})` (10认同)
  • 延迟对象实际上与承诺无关,它允许您在完成所有操作后加载多个脚本并执行功能.它只是检查$()是否准备就绪,如果是,它会解析,换句话说,它会在执行任何代码之前检查DOM是否准备就绪,就像document.ready那样,我找到了一个很好的附加示例承诺getScript online在代码中具有延迟的DOM就绪功能,并且决定保留它,因为它听起来像一个好主意. (9认同)
  • 这是因为在jQuery中默认关闭ajax中的缓存,打开它并删除查询字符串do:`$ .ajaxSetup({cache:true});`但这也会影响你不想要的其他ajax调用要缓存,[docs for getScript](http://api.jquery.com/jQuery.getScript/)上有更多内容,甚至还有一些关于创建名为cachedScript的缓存getScript函数的方法. (4认同)
  • 对不起,迟到了.有时你的方式仍然不太好用.不确定是什么原因.我想一次合并四个脚本文件.`$ .when($.getScript(scriptSrc_1),$.getScript(scriptSrc_2),$.getScript(scriptSrc_3),$.getScript(scriptSrc_4),$.Deferred(function(deferred){$(deferred.resolve);} )).done(function(){...})` (3认同)

And*_*rei 26

我实现了一个简单的函数来并行加载多个脚本:

功能

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

用法

getScripts(["script1.js", "script2.js"], function () {
    // do something...
});
Run Code Online (Sandbox Code Playgroud)


Fra*_*key 9

在前一个回调中加载以下所需的脚本,如:

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


Sal*_*n A 9

有时需要按特定顺序加载脚本.例如,jQuery必须在jQuery UI之前加载.此页面上的大多数示例并行(异步)加载脚本,这意味着无法保证执行顺序.如果没有排序,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");
});
Run Code Online (Sandbox Code Playgroud)
@import url("https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/blitzer/jquery-ui.min.css");

#slideshow1 {
  position: relative;
  z-index: 1;
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

两个队列中的脚本将并行下载,但是,每个队列中的脚本将按顺序下载,从而确保有序执行.瀑布图:

脚本的瀑布图