2017-09-27 62 views
4

之前,我有一個簡單的JavaScript循環如你所見如下:JavaScript的循環凍結瀏覽器並不能看到改變的環路

function runCode() { 
    $("#sample-span").removeAttr("style"); 
    for (var i = 0; i < 100000; i++) { 
     console.log(new Date()); 
    } 
    $("#sample-span").toggleClass("colorized"); 
} 

即切換類跨度在頁面如下:

<span id="sample-span" style="color: orange;">Sample Text</span> 
<input type="button" value="click to run" onclick="runCode()" /> 

<style> 
span { 
    color: blue; 
} 
.colorized { 
    color: red; 
} 
</style> 

問題是,循環運行時頁面凍結,無法看到跨度顏色變化。

我該如何解決這個問題?

jsfiddle link

UPDATE

親愛的朋友們,console.log(new Date());只是一個樣本,你認爲這裏運行的JavaScript重procces。

+2

你爲什麼要記錄一個'new Date()'100000次?這是非常昂貴的。 –

+0

親愛的@GhassenLouhaichi,這只是一個示例,假設在這裏運行繁重的JavaScript過程。 –

+1

然後你必須將你的進程分成異步代碼。 – str

回答

3

您有正在重過程之前改變顏色後添加一個小的延遲:

function runCode() { 
    $("#sample-span").toggleClass("colorized"); 
    setTimeout(runTask,10) 
} 

function runTask(){ 
    for (var i = 0; i < 100000; i++) { 
    console.log(new Date()); 
    } 
    $("#sample-span").toggleClass("colorized"); 
} 

JSFiddle

+0

這個工程,但仍然瀏覽器凍結。有沒有什麼辦法可以防止瀏覽器凍結? – hamed

+2

你不能。Javascript本質上是封鎖,如果你運行一個沉重的過程瀏覽器停止和凍結, 它的 正常 – Dellirium

+0

那麼你可以通過人工減慢過程來解決凍結問題,通過爲重過程的每個部分設置1毫秒超時:setTimeout(function(){console.log(new Date()); },1); – Shard

0

你究竟在做什麼?如果您希望文本顯示爲紅色,然後在指定時間後切換回來,那麼您真正需要的是setTimeout。

$("#sample-span").toggleClass("colorized"); 

    setTimeout(function() { $("#sample-span").toggleClass("colorized") }, 1000); 
-2

這是因爲您在點擊按鈕時切換了兩次。 如果你想改變跨度的顏色,當它完成,然後寫:function runCode() { $("#sample-span").toggleClass("colorized"); for (var i = 0; i < 100000; i++) { console.log(new Date()); } }

+0

,因爲我想切換顏色兩次 –

+0

雖然它可能是真的,但是您想切換兩次,但是該男子確實在他的帖子中指定了'如果您想在完成時更改顏色',沒有理由降低這個答案。它的100%正確。您沒有真正指定您想要在點擊時發生的事情,它可能會被解釋爲任何方式。 – Dellirium

+0

我認爲他在他的帖子@Dellirium中很清楚。這是一個不正確的答案,並沒有解決OP在半點面臨的問題。 – Shard

2

您的代碼存在的問題是,在執行DOM操作之前,JavaScript任務隊列會執行您的函數中的所有可用代碼。這意味着類切換調用被註冊,循環被執行,然後切換被連續執行,所以你看不到顏色的變化。

你需要做的是你的函數的第二部分發送到任務隊列的末尾類似如下內容:

function runCode() { 
    $("#sample-span").toggleClass("colorized"); 
    // allows the first toggle to execute and sends the loop and the second 
    // toggle to the end of the task queue 
    setTimeout(function() { 
     for (var i = 0; i < 5000; i++) { 
      console.log(new Date()); 
     } 
     $("#sample-span").toggleClass("colorized"); 
    }, 0); 
} 

我已經減少了迭代次數,減少瀏覽器鎖定,您仍然可以仍然看到顏色變化。