jQuery 中的 setTimeout 循环
setTimeout in jQuery with a loop
我有一个单词数组,我想延迟按顺序为每个单词更改一个 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()
似乎什么都没发生。
数组索引从 0 开始。
for (i = 1; i < array.length; i++)
应该是
for (i = 0; i < array.length; i++)
// ^
printWord(w)
不考虑连续延迟。第一次调用它时,它会告诉脚本在继续之前等待 1000 毫秒,并且每次后续调用(将在上一次调用后大约 1ms
发生)将 也 等待 1000 毫秒。这意味着脚本将在显示最后一个字之前等待大约 1 秒。
如果您要继续使用 setTimeout
,请将函数更改为以下内容:
function printWord(w, d) {
setTimeout(function() {
$("#word").text(w);
}, 1000 * d);
}
您正在使用 jQuery 作为依赖项。 Read the API and USE IT,或删除依赖项。
.text()
总是 returns 一个字符串。 .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) {
...
});
现在一起
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();
});
});
});
#offscreen_text {
display: none;
}
<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>
见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();
我已经为您创建了一个带有解决方案的 jsfiddle。未调用 readBook() 方法。如果你确实按照你的方式调用它,它看起来好像只做了数组的最后一个字,因为 setTimeouts 会同时发生,因为它们都是在迭代循环时调用的(几乎同时时间)...为了解决这个问题,我只是在超时中添加了一个乘数,表示你在循环中的距离。这个解决方案可能不是很有效,因为它会设置与单词一样多的超时。
另外,你有 i=1 其他人说会跳过数组的第一个单词。
http://jsfiddle.net/782pmv64/2/
function printWord(w, i) {
setTimeout(function() {
$("#word").text(w);
}, 800 * i);
}
您可以在不使用 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() 编辑 Fiddle:http://jsfiddle.net/gn6eh7t1/
你一遍又一遍地调用 printWord 函数,没有给它时间来执行代码,所以每次 运行s,它都会覆盖之前的 运行,只给它打印的机会最后一句话...
我将您的代码修改为一个函数,它只在知道还有更多单词要 "read" 时才调用自身。
我在全局范围内声明了数组以及字数统计的迭代器。一旦一个单词 'read',函数 readBook 将递增迭代器。
请运行 代码段。
<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>
问题:
- 所有
printWord
调用是同时进行的,因此函数内的每个 setInterval
调用将大致同时触发。
- 数组索引从
0
开始,因此 i =1
将跳过第一个单词。
- 虽然不是问题,但令人不快,但是在使用[=46=时不需要使用
onload
,您可以使用jQuery的document.ready
.
- 此外,无需在
$("#offscreen_text").text()
上调用 .toString()
,因为 jQuery.text
将始终 return 一个字符串,即使没有选择任何元素。
一个解决方案:
您可以使用基于 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>
不喜欢把这样的事情复杂化,解决方案可以像
一样简单
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);
一切都在同时发生。我传入索引值 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>
我有一个单词数组,我想延迟按顺序为每个单词更改一个 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()
似乎什么都没发生。
数组索引从 0 开始。
for (i = 1; i < array.length; i++)
应该是
for (i = 0; i < array.length; i++)
// ^
printWord(w)
不考虑连续延迟。第一次调用它时,它会告诉脚本在继续之前等待 1000 毫秒,并且每次后续调用(将在上一次调用后大约 1ms
发生)将 也 等待 1000 毫秒。这意味着脚本将在显示最后一个字之前等待大约 1 秒。
如果您要继续使用 setTimeout
,请将函数更改为以下内容:
function printWord(w, d) {
setTimeout(function() {
$("#word").text(w);
}, 1000 * d);
}
您正在使用 jQuery 作为依赖项。 Read the API and USE IT,或删除依赖项。
.text()
总是 returns 一个字符串。 .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) {
...
});
现在一起
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();
});
});
});
#offscreen_text {
display: none;
}
<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>
见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();
我已经为您创建了一个带有解决方案的 jsfiddle。未调用 readBook() 方法。如果你确实按照你的方式调用它,它看起来好像只做了数组的最后一个字,因为 setTimeouts 会同时发生,因为它们都是在迭代循环时调用的(几乎同时时间)...为了解决这个问题,我只是在超时中添加了一个乘数,表示你在循环中的距离。这个解决方案可能不是很有效,因为它会设置与单词一样多的超时。
另外,你有 i=1 其他人说会跳过数组的第一个单词。
http://jsfiddle.net/782pmv64/2/
function printWord(w, i) {
setTimeout(function() {
$("#word").text(w);
}, 800 * i);
}
您可以在不使用 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() 编辑 Fiddle:http://jsfiddle.net/gn6eh7t1/
你一遍又一遍地调用 printWord 函数,没有给它时间来执行代码,所以每次 运行s,它都会覆盖之前的 运行,只给它打印的机会最后一句话...
我将您的代码修改为一个函数,它只在知道还有更多单词要 "read" 时才调用自身。
我在全局范围内声明了数组以及字数统计的迭代器。一旦一个单词 'read',函数 readBook 将递增迭代器。
请运行 代码段。
<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>
问题:
- 所有
printWord
调用是同时进行的,因此函数内的每个setInterval
调用将大致同时触发。 - 数组索引从
0
开始,因此i =1
将跳过第一个单词。 - 虽然不是问题,但令人不快,但是在使用[=46=时不需要使用
onload
,您可以使用jQuery的document.ready
. - 此外,无需在
$("#offscreen_text").text()
上调用.toString()
,因为jQuery.text
将始终 return 一个字符串,即使没有选择任何元素。
一个解决方案:
您可以使用基于 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>
不喜欢把这样的事情复杂化,解决方案可以像
一样简单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);
一切都在同时发生。我传入索引值 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>