【问题标题】:Does jquery's $.get(...) ajax success function trigger when the file has completed downloading?文件下载完成后jquery的$.get(...) ajax成功函数会触发吗?
【发布时间】:2013-05-13 01:29:42
【问题描述】:

基本上我想知道当整个文件下载完成时,jQuery 的 $.get() 方法的“成功函数”是否被触发。我怀疑是这样,但只是想确定一下。

我正在使用一系列 $.get() 请求来加载页面文件(CSS、javascript 等),同时显示“加载屏幕”。

在请求的每次成功回调中,我都会加载下一个文件,直到它们最终全部完成,然后我会移除加载屏幕。

问题是随机的,通常在慢速连接(网站专为移动浏览而设计)时,加载屏幕会消失,但该网站的 CSS 直到大约 1-2 秒后才应用,因此用户将看到一个非在将 CSS 应用到按钮等之前的 -styled 网站。

这是我用来加载资源的代码

if(!window.MyResourceLoader) window.MyResourceLoader = {};

// list of resources to load
MyResourceLoader.MyResources = new Array(
  "include/resources/.....css",
  "include/resources/.....css",
  "include/modules/.......js",
  "include/...............js",
  "include/...............js");

// reverse the array so we load it in the order above
MyResourceLoader.MyResources.reverse();

MyResourceLoader.resourcesToLoad = MyResourceLoader.MyResources.length;

/**
 * Recursive function - loads the resources
 */
MyResourceLoader.loadMyResources = function()
{
  // exit condition - stop recurring if we've run out of resources to load
  if(this.MyResources.length < 1)
  {
    $(".meter > span").each(function() {
      $(this).stop().animate({
          width: "100%"
        }, 300);
    });
    return;
  }

  // get the next resource to load
  var resource = this.MyResources.pop();

  // if the resource is a css file, append it to the head
  if(resource.match(/css$/))
  {
    // append timestamp to resource
    resource += ("?" + new Date().getTime());

    // ie support
    if(document.createStyleSheet)
      document.createStyleSheet(resource);
    else
      $("head").append($('<link type="text/css" rel="stylesheet" href="' + resource + '">'));

    // recusivley load resources
    this.loadMyResources();
  }
  else if(resource.match(/\.js$/))
  {
    // append timestamp to resource
    resource += ("?" + new Date().getTime());

    // if the resource is a js file, make a request for it
    $.get(resource, function()
    {
      // on successful request of the file, make another call to load resource
      MyResourceLoader.loadMyResources();
    });
  }
}

最终的 javascript 文件是一个 'load end' .js 文件,它执行以下操作:

// fade out the loading screen
$('#webapp-loader').css('opacity',0);
setTimeout(function()
{
  $('#webapp-loader').remove();
}, 1000);

如您所见,加载结束时甚至还有 1 秒的缓冲区,然后才会移除加载屏幕。

【问题讨论】:

  • 只是重新阅读代码,我想我发现了我的问题:) - 资源加载只是将 CSS 文件附加到文档的头部,这会触发 CSS 文件的下载 - 所以上面的代码不会等待头部中的 CSS 完成下载,然后才会认为它“完成加载”

标签: javascript jquery css mobile loading


【解决方案1】:

是的 $.get() 下载整个文件,正如我在上面评论的那样,我的问题是资源加载只是将 CSS 文件附加到文档的头部,这会触发 CSS 文件的下载 - 所以上面的代码不会等待头部中的 CSS 完成下载,然后才会认为它“完成加载”

【讨论】:

    【解决方案2】:

    通过将资源附加到 DOM 来加载资源时,它们不会立即加载。您必须收听onload 才能知道元素是否已加载其内容。问题是,unlike the script tag which has an almost reliable onload and onerror, the link tag doesn't。您无法检查样式表是否已加载。

    我建议您通过 AJAX 加载 CSS,以便了解何时加载 CSS。然后,您将返回的 CSS 放入页面中的样式标记中。至于JS,既然你用的是jQuery,你可以用getScript

    此外,您可以同时并行加载它们。这样,您将更快地加载它们。要跟踪它们,您可以使用每个 jQuery ajax 函数返回的承诺。然后,您可以使用 when 检查所有 Promise 何时已加载其资源。

    另外,您的方法可能过于复杂。这是一个较短的:

    //the resource list
    var resources = [
      'include/resources/.....css',
      'include/resources/.....css',
      'include/modules/.......js',
      'include/...............js',
      'include/...............js'
    ];
    
    //collection of promises to listen
    var promises = [];
    var timestamp = '?' + new Date().getTime();
    var current, ext, promise;
    
    //load each resource
    for(var i = 0; i < resources.length; ++i){
    
      current = resources[i];
    
      //RegExp-less extension extraction (assuming they end with extensions)
      ext = current.substr(current.lastIndexOf('.')+1).toLowerCase();
    
      //extension check
      if(ext === 'css'){
        promise = $.get(current + timestamp).done(function(css){
          //when the CSS AJAX finishes, append
          $('<style>').html(css).appendTo('head');
        });
      } else if(ext === 'js'){
        promise = $.getScript(current + timestamp);
      }
    
      //push the promise
      promises.push(promise);
    }
    
    //listen with all are done
    $.when.apply(null,promises).done(function(){
      //all done!
    });
    

    【讨论】:

      猜你喜欢
      • 2013-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-26
      • 1970-01-01
      相关资源
      最近更新 更多