2014-07-08 119 views
0

美好的一天!我正在學習JavaScript,並對定時器有問題。我只是想檢查整個頁面寫入後是否觸發onload事件,包括通過javascipt修改的文本。爲此,我想通過在字符之間產生200毫秒的延遲來減慢文字的寫入。如何在for(){}循環中使用setTimeout?

我使用的測試如下:

<!DOCTYPE html>  
<head> 
<meta charset="utf-8"> 
<title>Onload test</title> 
<script> 

    function load() { 
     alert("The page is considered loaded !"); 
    } 

    function writeSlowly(text, timer) { 
     var L= text.length; 
     var st = ""; 
     function write (seq) { 
      document.getElementById("st").innerHTML = seq; 
     }; 
     for (var i = 0; i < L; i += 1) { 
      st += text[i]; 
      setTimeout(write(st), timer); 
     }; 
    }; 

</script> 
</head> 
<body> 
<p id="st"></p> 
<script> 
    writeSlowly("This pages takes a while to load", 200); 
    window.onload = load; 
</script> 
</body> 
</html> 

頁面加載時不存在任何延遲都可言。實際上,我預計文本(32個字符長)大約需要32 x 200 ms =〜7秒。調試時(使用Firebug - 我使用Firefox 30),程序逐行執行,但計時器無效。該頁面幾乎即時顯示。

+1

可能重複[如何在JavaScript循環中添加延遲?](http://stackoverflow.com/questions/3583724/how-do-i-add-a-delay-in-a-javascript-循環) – Adam

+0

謝謝亞當,Cheruvian&al。我會進一步練習。 – RAH

+0

謝謝Cheruvian和Adam花時間寫出正確的解決方案。你的腳本都在工作。我會確保我理解它的要點。 – RAH

回答

0

您正在爲每個字母創建單獨的定時器,全部從時間0開始,所有都在200ms時間執行。

此外,setTimeout函數需要是一個回調函數(該函數將在計時器到期時被調用回去)。你傳給它一個null。 write()不會返回任何更少的函數。

所以你每次你打的循環時間實際上是寫每個字母,導致無延遲

要達到什麼樣的你想我會做線沿線的東西...

var str; 
var index = 0; 

function writeSlowly(text, timer) { 
    str = text; 
    setInterval(writeNext, timer); 
}; 
function writeNext() 
{ 
    if(index < str.length - 1) 
     document.getElementById("st").innerHTML = str.substring(0, ++index); 
    else 
     document.getElementById("st").innerHTML = str; 
} 
0

我做了一些修改並使其工作,您可以試試at this link

一個問題是您打電話給write函數,而不是將其設置爲回調函數。另一個問題是,你想寫的字符串在寫完之前已經完全填滿了。最後,對於所有寫操作,定時器被設置爲距當前時間200ms,而不是爲寫入的每個字符引入200ms的延遲。

更新後的Javascript如下。

function writeSlowly(text, timer) { 
    var L= text.length; 
    var st = ""; 
    var delay = 0; 
    for (var i = 0; i < L; i += 1) { 
     st += text[i]; 
     delay += timer 
     setTimeout(writer(st), delay); 
    }; 
} 

function writer(toWrite) { 
    return function() { 
     document.getElementById("st").innerHTML = toWrite; 
    } 
} 

編輯:
我更新the JSFiddle

當文本滾動完成後,它會觸發done()函數並運行任何您想在該點運行的代碼。

0

按照給出的答案,他們的分析(請參閱原始問題下方的註釋),我的首選答案如下 - 類似於Adam的 - 對於每個字符延遲2毫秒的2880個字符串幾乎完全爲5760毫秒。中間部分在下方,並且full answer on JS Fiddle

function writeSlowly(text, timer) { 
    var L= text.length; 
    var delay = 0; 
    for (var i = 0; i < L; i += 1) { 
     setTimeout(writer, delay += timer); 
    }; 
    function writer() { 
     if (!writer.seq) writer.seq = 0; // Create a function property that increments on each call. 
     document.getElementById("slowpara").innerHTML = text.substring(0, ++writer.seq); 
    } 
} 

我感謝StackOverflow社區,特別是Cheruvian和Adam的慷慨幫助。