2017-09-25 53 views
3

我有一個長期運行的JavaScript函數,看起來像這樣:更新DOM

window.myFunction = function() { 
    for(var i=0;i<500;i++){ 
     // calling a function here 
     document.getElementbyID('mySpan').innerHTML = "Completed step " + i + "/500" 
    } 
} 

我的函數調用另一個同步功能非常頻繁(我在這個例子中使用500),並且當用戶等待爲了完成任務,我想實現類似加載條的東西,但我在這裏更新了跨度。每次更新我的跨度時,是否可以強制進行DOM刷新?

+0

你有一個錯字['getElementById'](https://developer.mozilla.org/en-US/docs/Web/ API/Document/getElementById) –

回答

1

由於腳本在瀏覽器中一個單獨的線程運行,像你這樣的任何方法都需要完成DOM更新之前。但是,你可以做的是使用一個迭代函數,延遲時間很短,可以重新繪製瀏覽器。

下面是一個例子...

window.myFunction = function(i) { 
 
    // calling a function here - passing i as a parameter, if needed 
 
    document.getElementById('mySpan').innerHTML = "Completed step " + i + "/500"; 
 
    i++; 
 
    if (i <= 500) setTimeout(function() { myFunction(i) }, 1); 
 
} 
 

 
myFunction(0);
<span id="mySpan"></span>

+0

迭代函數是否具有最大深度並且在一定量的迭代之後可能會失敗?什麼是我可以經歷的最大迭代次數? –

+0

在這種情況下,沒有最大深度。這只是涉及遞歸的一個問題,在這種情況下,函數在調用之後就會死掉。所以雖然它似乎是遞歸的,但實際上並不是。 – Archer

2

您應該使用setTimeout方法在event queue上運行它,而不是在stack上運行它。因爲在運行時沒有delay,所以在for循環內不會看到更新。我增加了一個callback在繁重的工作後運行它。

//Heavy task function 
 
var heavyTask = function(i, callback) { 
 
    setTimeout(function() { 
 
    document.getElementById('mySpan').innerHTML = "Completed step " + i + "/500"; 
 

 
    //Callback to the caller saying the task is finished here and continue on 
 
    ///////////////////// 
 
    callback(); 
 

 
    }, 50); 
 
} 
 

 

 
var i = 0; 
 

 
//Call myFunction recursively. 
 
(window.myFunction = function() { 
 
    if (i < 500) { 
 
    heavyTask(i, function() { 
 
     i++; 
 
     window.myFunction(); 
 
    }); 
 
    } 
 
})();
<span id="mySpan"></span>

+0

如果被調用的函數比間隔更長會怎樣? – Archer

+0

@Archer我更新了答案。看一看。任務完成後,您應該從沉重的任務中調用'callback'。 – Thusitha