带有循环的jQuery中的setTimeout

时间:2015-02-16 04:19:50

标签: javascript jquery settimeout

我有一个单词数组,我想按顺序将div标记更改为每个单词。

<script>
    function printWord(w) {
    setTimeout(function() {
        $("#word").text(w);
        }, 1000);

     }

function readBook() {
    var array = $("#offscreen_text").text().toString().split(/[\s\n]+/);
    for (i =1; i < array.length; i++){
        printWord(array[i]);
    }

}
</script>
<body onload="readBook()">
<div id="word"></div>
<div id="offscreen_text">hi hello bye goodbye this is a test with some random text</div>
</body>

当我跑readBook()时似乎没有发生任何事情。

8 个答案:

答案 0 :(得分:5)

您可以在不使用for循环的情况下使用setInterval。

function readBook() {
    var array = $("#offscreen_text").text().toString().split(/[\s\n]+/);
    var i=0;
    setInterval(function(){
        $("#word").text(array[i]); i++;    
    },1000);   
}

演示:http://jsfiddle.net/sywzno5p/

使用clearInterval()编辑小提琴:http://jsfiddle.net/gn6eh7t1/

答案 1 :(得分:3)

数组索引从0开始。

for (i = 1; i < array.length; i++)

应该是

for (i = 0; i < array.length; i++)
//       ^

printWord(w)

不会导致连续延迟。它第一次被呼叫时,它会告诉脚本在继续之前等待1000ms,并且每次连续呼叫(将在前一次呼叫后的大约1ms处发生)也< / em>等待1000ms。这意味着脚本将在显示最后一个单词之前等待大约1秒钟。

如果您要继续使用setTimeout,请将功能更改为以下内容:

function printWord(w, d) {
    setTimeout(function() {
        $("#word").text(w);
    }, 1000 * d);
}

您正在使用jQuery作为依赖项。 Read the API and USE IT,或删除依赖项。

.text()总是返回一个字符串。 .toString()是不必要的。摆脱它。

$("#offscreen_text").text().toString().split(/[\s\n]+/);
//                         ^^^^^^^^^^^

此外,\s\n匹配,因此[\s\n]是多余的。简化为/\s+/

jQuery(function ($) {})document.ready的别名短手,这是调用readBook的合适方式:

function readBook($) {
    ...
}

jQuery(readBook);

setTimeout没有排队行为。使用delay(1000)queue(fn)

function printWord(w) {
    $('#word').delay(1000).queue(function (next) {
        $(this).text(w);
    });
}

使用简单的for循环迭代错误。 jQuery有一个实用程序$.each方法可以防止这样一个简单的错误:

$.each(array, function (index, value) {
    ...
});

现在一起

&#13;
&#13;
jQuery(function ($) {
  var words;
  words = $('#offscreen_text').text().split(/\s+/);
  $.each(words, function (i, word) {
    $('#word').delay(1000).queue(function (next) {
      $(this).text(word);
      next();
    });
  });
});
&#13;
#offscreen_text {
  display: none;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="word"></div>
<div id="offscreen_text">hi hello bye goodbye this is a test with some random text</div>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

请参阅http://jsfiddle.net/ta9q32v7/

function readBook() {
    var array = $("#offscreen_text").text().toString().split(/[\s\n]+/);
    var i = 0;
    setInterval(function(){ $("#word").text(array[i % array.length]); i++;}, 1000);
}

readBook();

答案 3 :(得分:1)

我为你创建了一个jsfiddle解决方案。没有调用readBook()方法。如果你用它写的方式调用它就会看起来好像它只是完成了数组的最后一个字,因为setTimeouts都会立即发生,因为它们都是在迭代循环时被调用的(几乎相同)时间)...为了解决这个问题,我只是在超时中添加了一个倍数,表示你在循环中的距离。这个解决方案可能效率不高,因为它会设置与单词一样多的超时。

另外,你有i = 1,其他人说过会跳过数组的第一个字。

http://jsfiddle.net/782pmv64/2/

function printWord(w, i) {
  setTimeout(function() {
    $("#word").text(w);
    }, 800 * i);
}

答案 4 :(得分:1)

你反复调用printWord函数而没有给它时间来执行代码,因此每次运行时它都会覆盖上一次运行,只给它打印最后一个单词...

我将你的代码修改为一个单独的函数,只有当它知道有更多的单词时才会调用自己&#34; read&#34;。

我在全局范围内声明了数组以及字数统计的迭代器。一旦一个单词“读取”,readBook函数就会递增迭代器。

请运行代码段。

&#13;
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="word"></div>
<div id="offscreen_text">hi hello bye goodbye this is a test with some random text</div>
<script>
  var i = 0;
  var array = $("#offscreen_text").text().toString().split(/[\s\n]+/);

  function readBook() {

    $("#word").text(array[i]);
    i++;
    if (i < array.length) {
      setTimeout(readBook, 1000);
    }


  }



  readBook();
</script>
&#13;
&#13;
&#13;

答案 5 :(得分:1)

问题:

  1. 所有printWord次呼叫都是同时进行的,因此该功能内的每次setInterval呼叫都会在大致相同的时间内发起。
  2. 数组索引从0开始,因此i =1将跳过第一个单词。
  3. 虽然不是一件令人不快的问题,但在使用jQuery时你不需要使用onload,你可以使用jQuery的document.ready
  4. 此外,无需在.toString()上致电$("#offscreen_text").text(),因为jQuery.text将始终返回字符串,即使未选择任何元素。
  5. 解决方案:

    您可以使用基于setTimeout的循环来迭代单词。

    $(function() {//document.ready wrapper (no need for onload).
      function readBook() {
        var array = $("#offscreen_text").text().split(/[\s\n]+/);
        var wordIndex = 0;//Keep track of the word to show.
        var nextWord = function() {
          if (wordIndex < array.length) {//Check if there are more words to show.
            $("#word").text(array[wordIndex]);//Set the word.
            setTimeout(nextWord, 1000);//Set the next word timeout.
            wordIndex++;//Increment the word counter.
          }
        }
        nextWord();//Start the word loop.
      }
      readBook();
    });
    #offscreen_text {
      display: none;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <div id="word"></div>
    <div id="offscreen_text">hi hello bye goodbye this is a test with some random text</div>

答案 6 :(得分:0)

不要过于复杂化这样的事情,解决方案可以像

一样简单
function printWord(word,index,life) {
    setTimeout(function() {
         $("#word").text(word);
    }, index*life);

}

function readBook() {
    var array = $("#offscreen_text").text().split(/[\s\n]+/);

    for (i =0; i < array.length; i++){
        printWord(array[i],i,1000);
    }

}

$(readBook);

基本上,你有时间在上一次

之后发生X时间

这也可以在不使用jQuery的情况下完成

 function printWord(w,i,life) {

    setTimeout(function() {
        document.getElementById("word").innerText = w;
    }, i*life);

 }

function readBook() {
    var array = document.getElementById("offscreen_text").innerText.split(/[\s\n]+/);

    for (i =0; i < array.length; i++){
        printWord(array[i],i,1000);
    }

}

document.addEventListener('DOMContentLoaded', readBook);

答案 7 :(得分:0)

一切都在发生。我传入索引值i乘以1000 ms。

<!DOCTYPE html>
<html>
<head>
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
</head>
<body onload="readBook()">
<div id="word"></div>
<div id="offscreen_text">hi hello bye goodbye this is a test with some random text</div>
<div id="sentence">This is some sentence that has the word is.</div>
<script>
    function printWord(w,i) {
    setTimeout(function() {
        $("#word").text(w);
        }, 1000*i);

     }

function readBook() {
    var array = $("#offscreen_text").text().toString().split(/[\s\n]+/);
    for (i =0; i < array.length; i++){
        printWord(array[i],i);
    }

}
</script>
</body>
</html>