0

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

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

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

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

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

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 秒的缓冲区,然后才移除加载屏幕。

4

2 回答 2

0

通过将资源附加到 DOM 来加载资源时,它们不会立即加载。您必须聆听onload才能知道元素是否已加载其内容。问题是,script标签具有几乎可靠的onloadand不同onerrorlink标签没有. 您无法检查样式表是否已加载。

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

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

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

//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-13T01:44:51.747 回答
0

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

于 2013-05-13T01:35:33.450 回答