Javascript 为循环设置内部超时
我希望使用以下代码逐个字符显示字符串:Javascript 为循环设置内部超时,javascript,loops,settimeout,Javascript,Loops,Settimeout,我希望使用以下代码逐个字符显示字符串: function initText() { var textScroller = document.getElementById('textScroller'); var text = 'Hello how are you?'; for(c = 0; c < text.length; c++) { setTimeout('textScroller.innerHTML += text[c]', 1000
function initText()
{
var textScroller = document.getElementById('textScroller');
var text = 'Hello how are you?';
for(c = 0; c < text.length; c++)
{
setTimeout('textScroller.innerHTML += text[c]', 1000);
}
}
window.onload = initText;
函数initText()
{
var textcroller=document.getElementById('textcroller');
var text='你好吗?';
对于(c=0;c
它不起作用了。。我做错了什么?试试这个:
function initText()
{
var textScroller = document.getElementById('textScroller');
var text = 'Hello how are you?';
for(c = 0; c < text.length; c++)
{
setTimeout("textScroller.innerHTML += '" + text[c] + "'", 1000 + c*200);
}
}
window.onload = initText;
函数initText()
{
var textcroller=document.getElementById('textcroller');
var text='你好吗?';
对于(c=0;c
for循环一次为每个字符设置超时,因此它们不会按顺序出现,而是一次全部出现。setTimeout应包含另一个setTimeout的代码,该setTimeout将包含要显示的下一个字符
所以像这样的东西(没有测试这个)
试着这样做:
function initText()
{
var textScroller = document.getElementById('textScroller');
var text = 'Hello how are you?';
var c = 0;
var interval = setInterval(function() {
textScroller.innerHTML += text[c];
c++;
if(c >= text.length) clearInterval(interval);
}, 1000);
}
注意:我添加了clearInterval
,以便在需要时停止它。尝试使用闭包:
function init() {
var textScroller = document.getElementById('textScroller');
var text = 'Hello how are you?';
var c = 0;
function run() {
textScroller.innerHTML += text[c++];
if (c<text.length)
setTimeout(run, 1000);
}
setTimeout(run, 1000);
}
init()
函数init(){
var textcroller=document.getElementById('textcroller');
var text='你好吗?';
var c=0;
函数运行(){
textcroller.innerHTML+=文本[c++];
如果(c当前,您正在定义18个超时,所有超时都将立即执行。
第二个问题是,您传递指令以作为字符串执行。在这种情况下,代码将无法访问initText中定义的所有变量,因为求值代码将在全局范围内执行
依我看,这应该可以做到
function initText(){
var textScroller = document.getElementById('textScroller');
var text = 'Hello how are you?';
var c = 0;
(function(){
textScroller.innerHTML += text.charAt(c++);
if(text.length > c){
setTimeout(arguments.callee, 1000);
}
})();
}
我想分享一个片段(基于Soufiane Hassou的回答)。它扩展到当你在固定的时间间隔内替换for循环体在某个数组上迭代时的情况。基本上是相同的同步循环,但有“睡眠”暂停(因为javascript不是同步编程语言)
用法示例:
loop([1, 2, 3, 4], function(index, elem){
console.log('arr[' + index + ']: ' + elem);
});
在Node JS中测试。希望对大家有所帮助
编辑>
以下更新使代码与执行大量“原型化”(如jQuery或prototype)的LIB一起可用:
如果您想保留setTimeOut(而不是setInterval)并使用命名函数(而不是在setTimeOut调用中计算代码块),那么这可能会很有帮助:
var b = {
textScroller: document.getElementById('textScroller'),
text: "Hello how are you?"
};
function initText() {
for(c = 0; c < b.text.length; c++) {
setTimeout("append("+c+")", 1000 + c*200);
}
}
function append(c) {
b.textScroller.innerHTML += b.text[c];
}
window.onload = initText;
var b={
textScroller:document.getElementById('textScroller'),
文字:“你好,你好吗?”
};
函数initText(){
对于(c=0;c
通过以上步骤,您可以向append函数传递一个参数
要传递多个参数,下一个代码将执行以下操作:
var glo=[];
函数initText()
{
var textcroller=document.getElementById('textcroller');
var text=“你好吗?”;
var超时时间;
对于(c=0;c
使用上面的方法,您只有一个全局数组glo
。在循环中,您将创建新的数组成员到glo
,并在append()
函数中使用作为参数传递的索引引用这些成员
警告:第二个代码示例并不意味着是OP:s问题的最佳或最合适的解决方案,但可能会在其他与setTimeOut相关的问题中受益,例如,当有人想要进行演示或性能测试时,需要在延迟后调用某些功能。此代码的优点是利用for循环(许多编码人员希望使用for循环)以及使用内部循环的可能性,以及将循环时间状态中的局部变量“发送”到超时函数的能力。甚至比@yauhen yakimovich更通用:
使用超时
:
注释中指出的两种方法之间的细微差别--repeat
方法仅在回调执行后重复,因此如果您有“slow”回调它不会每隔delay
ms运行一次,而是在执行之间每隔delay
重复一次,而loop
方法将每隔delay
ms触发回调。要提前停止,repeat
使用对象作为返回的标识符,因此改用clearTimeout(timer.t)
用法:
正如@soufiane hassou所言:
var textScroller = document.getElementById('textScroller');
var text = 'Hello how are you?';
var c = 0;
var interval = repeat/* or loop */(function() {
textScroller.innerHTML += text[c];
c++;
return (c >= text.length);
}, 1000);
如前所述,提前停车将是:
/* if repeat */ clearTimeout(interval.t);
/* if loop */ clearInterval(interval);
以级联方式循环可能更好。例如,使div褪色:
div=document.createElement('div');
div.style.opacity=1;
setTimeout(function(){fade(1);},3000);
function fade(op){
op-=.05;
if(op>0) setTimeout(function(){div.style.opacity=op;fade(op);},30);
else document.body.removeChild(div);
}
编辑以删除测试变量并将文本[c]作为字符串附加到单引号中。如果文本包含'
,``或换行符,则会失败。最好避免在字符串中创建和执行代码,就像字符串参数超时一样。您是对的,setInterval是一个更好的主意,没有考虑itI,谢谢!在本例中,没有(标准)循环已定义。因此,在本例中,函数充当循环?这是新的,但对我来说很有趣:)循环的是setInterval
。它就像在setTimeout
上循环一样:)如果设置innerHTML时出错怎么办?我会告诉你:又一个错误,又一个错误,等等。setInterval
是危险的。反复使用setTimeout
更安全。很高兴了解setInterval和循环,
var repeat = (function () {
return function repeat(cbWhileNotTrue, period) {
/// <summary>Continuously repeats callback after a period has passed, until the callback triggers a stop by returning true. Note each repetition only fires after the callback has completed. Identifier returned is an object, prematurely stop like `timer = repeat(...); clearTimeout(timer.t);`</summary>
var timer = {}, fn = function () {
if (true === cbWhileNotTrue()) {
return clearTimeout(timer.t); // no more repeat
}
timer.t = setTimeout(fn, period || 1000);
};
fn(); // engage
return timer; // and expose stopper object
};
})();
var loop = (function () {
return function loop(cbWhileNotTrue, period) {
/// <summary>Continuously performs a callback once every period, until the callback triggers a stop by returning true. Note that regardless of how long the callback takes, it will be triggered once per period.</summary>
var timer = setInterval(function () {
if (true === cbWhileNotTrue()) clearInterval(timer);
}, period || 1000);
return timer; // expose stopper
};
})();
var textScroller = document.getElementById('textScroller');
var text = 'Hello how are you?';
var c = 0;
var interval = repeat/* or loop */(function() {
textScroller.innerHTML += text[c];
c++;
return (c >= text.length);
}, 1000);
/* if repeat */ clearTimeout(interval.t);
/* if loop */ clearInterval(interval);
div=document.createElement('div');
div.style.opacity=1;
setTimeout(function(){fade(1);},3000);
function fade(op){
op-=.05;
if(op>0) setTimeout(function(){div.style.opacity=op;fade(op);},30);
else document.body.removeChild(div);
}