如何在for(){}循环中使用setTimeout?

时间:2014-07-08 18:09:56

标签: for-loop callback settimeout

美好的一天!我正在学习javascript并且计时器有问题。我只想检查整个页面写入后是否触发onload事件,包括通过javascipt修改的文本。为此,我想通过在字符之间引入200毫秒的延迟来减慢文本的写入速度。

我使用的测试如下:

<!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),程序逐行完成,但计时器无效。页面几乎瞬间显示。

3 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分: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()功能并运行你想要在那时运行的任何代码。

答案 2 :(得分:0)

根据给出的答案,他们的分析(见原始问题下面的评论)我的首选答案如下 - 与亚当一样 - 对于2880个字符串,每个字符延迟2毫秒,几乎完全需要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的慷慨帮助。