2013-05-13 46 views
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文件是一個「負載端」的.js文件做以下操作:

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

正如你所看到的那樣,在加載結束之前,甚至會有1秒的緩衝區,然後它將刪除加載屏幕。

+0

只是重新閱讀代碼,我想我找到了我的問題:) - 資源加載只追加CSS文件到文件的頭部,這會觸發CSS的下載文件 - 所以上面的代碼不會等待頭部的CSS完成下載之前,它認爲它是'完成加載' – jenovachild 2013-05-13 01:32:51

回答

0

是$ .get()下載整個文件,正如我上面評論我的問題是,資源加載只是將CSS文件附加到文檔的頭部,這會觸發CSS文件的下載 - 所以上面的代碼不會等待頭部的CSS完成下載,然後才認爲它已完成加載。

0

當通過將資源添加到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函數返回的promise。然後您可以使用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! 
}); 
相關問題