Javascript 如何在for…循环中使用setTimeout

Javascript 如何在for…循环中使用setTimeout,javascript,Javascript,我想要的是(新闻代码类型功能): 从ul标签上获取李的列表 循环浏览所有的li并获取文本 通过firefox console.log()在控制台中显示文本 获取下一个li并重复,直到显示所有li 这就是目标,但是setTimeout并不像我想象的那样运行。只显示最后一次迭代(“Post Four”)。“第四个帖子”连续四次出现 <body> <ul id="post_list"> <li>Post One</li> <li>Post

我想要的是(新闻代码类型功能):

  • 从ul标签上获取李的列表
  • 循环浏览所有的li并获取文本
  • 通过firefox console.log()在控制台中显示文本
  • 获取下一个li并重复,直到显示所有li
  • 这就是目标,但是setTimeout并不像我想象的那样运行。只显示最后一次迭代(“Post Four”)。“第四个帖子”连续四次出现

    <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>
    
    
    
    • 张贴一
    • 第二站
    • 第三站
    • 四柱
    var ul=document.getElementById('post_list'); var li=ul.getElementsByTagName('li'); 对于(变量x=0;x
    发生这种情况的原因是闭包。for循环块周围有闭包,因此当您引用“li_text”时,它始终等于li_text设置的最后一个值。for循环不会为循环中的每个迭代创建单独的闭包。

    发生这种情况的原因是闭包。for循环块周围有闭包,因此当您引用“li_text”时,它始终等于li_text设置的最后一个值。for循环不会为循环中的每个迭代创建单独的闭包。

    更改此选项:

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

    for(var x=0;x
    更改此选项:

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

    for(var x=0;x
    我们把一些代码移动一下怎么样。。。解决关闭问题

    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);
    }
    
    var ul=document.getElementById('post_list');
    var li=ul.getElementsByTagName('li');
    对于(变量x=0,xl=li.length;x

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

    我们把一些代码移动一点怎么样。。。解决关闭问题

    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);
    }
    
    var ul=document.getElementById('post_list');
    var li=ul.getElementsByTagName('li');
    对于(变量x=0,xl=li.length;x

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

    正如Greg提到的,问题在于闭包只评估一次。没有人发布解决方案,所以这里有一个。这将使用添加每次生成回调函数的函数:

    加:

    然后像这样在循环中使用它:

    for(var x=0; x < li.length; x++){
        var li_text = li[x].childNodes[0].nodeValue;
        setTimeout(getShowTextCallback(li_text), 1000);
    }
    
    for(变量x=0;x
    正如Greg提到的,问题在于闭包只计算一次。没有人发布解决方案,所以这里有一个。这将使用添加每次生成回调函数的函数:

    加:

    然后像这样在循环中使用它:

    for(var x=0; x < li.length; x++){
        var li_text = li[x].childNodes[0].nodeValue;
        setTimeout(getShowTextCallback(li_text), 1000);
    }
    
    for(变量x=0;x
    经典的循环函数问题。这个问题已经被一遍又一遍地问了……检查右边栏的“相关”列表(基本上与您键入问题标题时得到的列表相同,您看到了吗?)。循环的可能重复基本上要求4个计时器几乎同时启动,1000毫秒后,每一次都几乎在同一时间结束。@MattBall-Huh,当时一定选择了错误的一次,实际上是想提出一个setTimeout问题。典型的函数在循环中的问题。这个问题已经被一遍又一遍地问了……检查右边栏的“相关”列表(基本上与您键入问题标题时得到的列表相同,您看到了吗?)。循环的可能重复基本上要求4个计时器几乎同时启动,每一个都在1000毫秒后几乎相同的时间结束。@MattBall-Huh,当时一定选错了,实际上想提出一个setTimeout问题。这是一个非常复杂的答案,一个治疗症状而不是问题的真实案例。这是一个非常复杂的答案,这是一个治疗症状而不是问题的真实案例。您没有缓存长度。你意识到生活是对的吗?而且
    .length
    很昂贵我不会解决代码的所有问题。。。否则,我只会回答一半jQuery问题,“YU不使用DOM”而不是复制粘贴错误代码的借口。您还可以使用不带过滤器的
    .childNodes