如何在for ...循环中使用setTimeout

时间:2011-11-09 20:06:38

标签: javascript

我想要的是这个(新闻自动收报机类型功能):

  1. 从ul标签中获取li的列表
  2. 遍历所有li并获取文本
  3. 通过firefox console.log()
  4. 在控制台中显示文本
  5. 获取下一个li并重复直到所有li已经显示
  6. 这就是目标,但是setTimeout没有像我想象的那样运行。仅显示最后一次迭代(“后四次”)。那个(“后四”)连续四次出现。

    <body>
    <ul id="post_list">
     <li>Post One</li>
     <li>Post Two</li>
     <li>Post Three</li>
     <li>Post Four</li>
    </ul>
    
    <script type="text/javascript">
    var ul = document.getElementById('post_list');
    var li = ul.getElementsByTagName('li');
    
    for(var x=0; x < li.length; x++){
        var li_text = li[x].childNodes[0].nodeValue;
        setTimeout(function(){showText(li_text)}, 1000);
    }
    
    function showText(text) {
        console.log(text);
    }           
    </script>
    </body>
    

4 个答案:

答案 0 :(得分:4)

发生这种情况的原因是因为关闭。 for循环块周围有闭包,所以当你引用'li_text'时,它总是等于li_text设置为的 last 值。 for循环不会为循环中的每次迭代创建一个单独的闭包。

答案 1 :(得分:2)

正如格雷格所说,问题在于关闭仅评估一次。没有人为此发布解决方案,所以这里有一个。这使用添加每次生成回调函数的函数:

添加:

function getShowTextCallback(text) {
    return function(){showText(text)}
}

然后在循环中使用它:

for(var x=0; x < li.length; x++){
    var li_text = li[x].childNodes[0].nodeValue;
    setTimeout(getShowTextCallback(li_text), 1000);
}

答案 2 :(得分:0)

改变这个:

for(var x=0; x < li.length; x++){
    var li_text = li[x].childNodes[0].nodeValue;
    setTimeout(function(){showText(li_text)}, 1000);
}

要:

for(var x=0; x < li.length; x++) (function() {
    var li_text = li[x].childNodes[0].nodeValue;
    setTimeout(function(){showText(li_text)}, x * 1000);
})()

答案 3 :(得分:0)

我们只是稍微移动一些代码......取出关闭问题......

var ul = document.getElementById('post_list');
var li = ul.getElementsByTagName('li');

for (var x = 0, xl = li.length; x < xl; x++) {
    var li_text = li[x].innerText || li[x].textContent; // does IE support textContent??
    showText(li_text, x * 1000);
}

function showText(text, delay) {
    setTimeout(function() {
        console.log(text);
    }, delay);
}

我假设你想要连续的延迟(因此循环)。因为setTimeout没有阻塞,所以你需要在函数上进行回调以调用下一个setTimeout,或者你需要使用新的延迟专门增加每个函数调用。