2012-04-10 44 views
3

簡而言之,我有一個ajax調用,有時會在頁面加載完成之前完成,因此我試圖在$(fn)中包裝回調,但如果頁面已加載,回調不會觸發。任何人都可以很好地解決這個問題?

$.get('/foo.json', function(data){ 
    $(function(){ 
     // won't get here if page ready beats the ajax call 

     // process data 
     $('.someDiv').append(someData); 
    }); 
}); 

是的,我知道,如果我翻的,將總是工作的秩序,但後來我的Ajax調用會不必要地推遲到文件已準備就緒。

+0

你還沒有嘗試過這一點,是嗎? – Bergi 2012-04-10 17:16:44

+0

@Bergi - 是的,我有 – 2012-04-10 17:18:27

+0

@cwolves這不起作用是'$ .ready'中的一個錯誤。它應該只是工作 – Raynos 2012-04-10 17:31:32

回答

1

不,添加到onDOMready的函數將始終執行,並且如果事件已經發生,將立即執行。請參閱文檔http://api.jquery.com/ready/:只有在您使用$(document).bind("ready")時,它纔會在事件已經觸發時執行。

非觸發事件處理程序可能的原因是其他處理程序拋出錯誤。 jQuery有一個用於待執行的處理程序的內部數組,處理本機DOM負載事件的方法只是迭代它。如果其中一個較早的處理程序出現錯誤,則循環會中斷並且之後添加的其他處理程序將不會被調用。

+0

很好。他們不是:) ___exact___代碼:'〜function($,RC){0} {0} {0} {0} {0} ; \t \t $(函數(){ \t \t \t的console.log( '步驟2'); \t \t \t $。replaceTmpl('financial_plan_template'); \t \t \t WBR.initSection('#financial-plan'); \t \t}); \t}); }(jQuery,window.RazorCharts);''step1'總是被記錄下來。 'step2'有時會。 – 2012-04-10 17:16:19

+0

您能否將代碼移到您的問題中? – Bergi 2012-04-10 17:23:18

+0

@cwolves,是的,他們是。你的代碼有其他問題。 http://jsfiddle.net/CpPR3/ – 2012-04-10 17:23:28

0

將您的結果加載到一個全局變量中,並將它們加載到DOM準備就緒。關鍵是如果結果爲空,則使用setTimeout迭代,直到它們不是。

var result; 
$.get("/foo.json", function(data) { 
    result = data; 
}); 

function insertAJAX() { 
    if(result !== undefined) { 
     $(".someDiv").append(result); 
    } else { 
     setTimeout(insertAJAX, 250); 
    } 
} 

$(function() { 
    insertAJAX(); 
}); 

注意,您可以添加一個超時計數器停止了一定時間後想,如果你的AJAX不會返回結果無論出於何種原因。

1
var result; 
$(document).on('ready.specialAjax', function() { 
    if (result) { 
     $(".someDiv").append(result); 
    } 
}); 
$.get('/foo.json').done(function (data) { 
    if ($(".someDiv").length) { 
     $(".someDiv").append(data); 
     $(document).off('ready.specialAjax'); 
    } 
    else { 
     result = data; 
    } 
}); 

基本上,如果可以的話,ajax會立即嘗試追加到someDiv。否則,它在運行時將其存儲在result中的ajax結果和document.ready自行追加它。完成.off是爲了防止數據被附加兩次以防ajax成功完成。這應該不重要,因爲在這種情況下結果將是空白的,但只是爲了清潔。

+0

我喜歡這個回答。這正是自定義事件處理程序的用途。 – 2012-04-10 17:20:58

0

您將需要檢查dom是否已準備好在AJAX回調中以確保您準備好後立即追加還是立即追加。見下面的代碼,

var isDomReady = false; 

$.get('/foo.json', function(data){ 
    if (isDomReady) { 
     $(function(){ $('.someDiv').append(someData); }); 
    } else { 
     $('.someDiv').append(someData); 
    } 
}); 

$(function(){ 
    isDomReady = true; 
    // and all you ready code 
}); 
0

它不會傷害這樣做。

var getData; 
$.get('/foo.json', function(data){ 
    getData = data; 
}); 
$(function() { 
    var intt = setTimeinterval(function() { 
     if(getData.length) { 
       //do your task 
       clearInterval(intt); 
     } 
    }, 100); 
}); 
+0

DOM準備好後如果完成AJAX需要超過100ms的時間會怎麼樣?在這些情況下,Set Interval始終是不好的..你永遠不知道需要多長時間才能得到回覆。 – 2012-04-10 17:23:15

+0

@SKS,你是什麼意思?不會再經過100ms的輪次間隔檢查 – Starx 2012-04-10 17:24:40

+1

@Statx mm ..我的壞..但仍然不是一個好辦法來處理這種情況。 – 2012-04-10 17:27:07

1

這裏是另一種使用延遲的方法。顯然,你可以使用deferreds與document.ready,它只是一個有點古怪:

$(document).data("readyDeferred", $.Deferred()).ready(function() { 
    $(document).data("readyDeferred").resolve(); 
}); 
var jqxhr = $.get('/foo.json'); 
$.when(jqxhr, $(document).data('readyDeferred')) 
    .done(function (jqxhr) { 
     $(".someDiv").append(jqxhr[2].responseText); 
    });