Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为循环设置内部超时_Javascript_Loops_Settimeout - Fatal编程技术网

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);
}