2013-09-24 41 views
1

我正在使用HTML5畫布。我已經在canvas元素中加載了大小爲7MB的圖像。在我的頁面上,我有一個ConvertImage按鈕:HTML5 Canvas toDataURL()阻止JavaScript調用?

var imageUrl; 
$("#ConvertImage").click(function() { 
    $("#Spinner").show(); 
    imageUrl = $("#canvas")[0].toDataURL("image/png;base64;"); 
}); 

微調只是一個動畫的gif。事實證明,當我嘗試在下一個語句中檢索imageUrl時,Spinner沒有立即顯示。沒有第二次操作,微調器就立即顯示出來。感覺微調器在toDataURL()操作完成後顯示。

這很奇怪,因爲show()函數在toDataURL()操作之前執行。

我該如何解決這個問題?

回答

3

對於更新的微調,儘量讓創建一個額外的更新事件對代碼進行修改。

您可以通過使用setTimeout做到這一點:

$("#ConvertImage").click(function() { 
    $("#Spinner").show(); 

    /// add an event to be executed in about 100ms 
    setTimeout(function() { 
     imageUrl = $("#canvas")[0].toDataURL(); 
     /// done, optionally call some other function... 
    }, 100); 

}); 

這將給.show()一些時間來完成和setTimeout活動結束後,將進行排隊。

您可能需要/想要更改我在此處開始的值(100毫秒)。

也有在代碼中的錯誤,它可能沒有什麼影響,但它不會傷害得到它的權利 -

toDataURL參數必須是圖像專用型,即。 image/png,image/jpeg,image/webp等base64部分不應該在那裏(當你從一個存在的data-uri複製圖像類型時可能會出現這種情況)。由於PNG是默認情況下沒有必要在任何情況下,指定它 - 簡單地使用:

var dataUri = myCanvas.toDataURL(); /// default is image/png, also when it cannot 
            /// detect a supported type 

var dataUri = myCanvas.toDataURL('image/png'); 
var dataUri = myCanvas.toDataURL('image/jpeg'); 

+0

將檢查以'.complete'被硬編碼相比貝滕任意100ms值? – cherouvim

1

我認爲您的問題與以下問題中描述的問題非常相似:innerHTML can't be trusted: Does not always execute synchronously

基本上,DOM更新並不是真正的「同步」,這意味着只有在您的當前代碼完成後,您的顯示微調器的請求才會發生。

您需要牢記JavaScript執行是單線程的,因爲任何代價高昂的計算都會凍結您的UI。 顯示微調器在進行像AJAX請求那樣的長時間異步操作時很有意義,但在執行像toDataURL這樣的阻止同步操作時無用,因爲UI在完成前沒有更新的機會。

如果您需要執行長的同步代碼,那麼就來看看網絡工作者:http://www.html5rocks.com/en/tutorials/workers/basics/