简体   繁体   English

setTimeout不递归调用匿名函数

[英]setTimeout not recursively calling anonymous function

I was asked to make a small div cycle a fade in and fade out effect. 我被要求做一个小div循环淡入淡出效果。 There are several ways to do this, but I am wondering why the following only runs the effect one time. 有几种方法可以做到这一点,但是我想知道为什么下面的方法只运行一次。

 $(document).ready(function() {
    (function(){
      setTimeout(function(){$("#foo").fadeOut().delay(800).fadeIn(800);},0)
    })();
 });

As far as I can tell, the function should run recursively, but it doesn't. 据我所知,该函数应该递归运行,但事实并非如此。

I went with setInterval(function(){$("#foo").fadeOut().delay(800).fadeIn(800);}, 0); 我选择了setInterval(function(){$("#foo").fadeOut().delay(800).fadeIn(800);}, 0); because it gets the job done, but I'd still like to know why setTimeout didn't work as I expected. 因为它可以完成工作,但是我仍然想知道为什么setTimeout不能按我预期的那样工作。

Please don't use setInterval for this . 请不要为此使用setInterval

You are calling setInterval with a delay of 0. This means it will continue to execute - faster than the animations can complete. 您正在以0的延迟调用setInterval 。这意味着它将继续执行-比动画可以完成的速度快。 This will keep adding animation effects to jQuery's internal queue, building memory usage over time. 这将继续向jQuery的内部队列中添加动画效果,从而随着时间的推移建立内存使用情况。

You could increase the delay time to a value at least equal to the length of the animations, but this is unreliable. 可以将延迟时间增加到至少等于动画长度的值,但这是不可靠的。 Timers (and animations) can be delayed by other code, and this sort of hardcoding should be avoided. 计时器(和动画)可能会被其他代码延迟,因此应避免这种硬编码。

Instead, take this approach: 相反,请采用以下方法:

function fadeInOut() {
    $("#foo").fadeOut().delay(800).fadeIn(800, fadeInOut);
}
fadeInOut();

Here, you are passing the fadeInOut function as a callback that is automatically called when jQuery finishes the fadeIn animation. 在这里,您fadeInOut函数作为回调传递,当jQuery完成fadeIn动画时会自动调用该fadeIn This guarantees that a new cycle of animations won't begin until the previous cycle has completed. 这样可以确保新的动画循环不会开始,直到前一个循环完成为止。

setTimeout(fx,delay) is going to be invoked one time when the delay elapses. 延迟过去后,将调用setTimeout(fx,delay)一次。 Calling it with a delay of 0 in this case is the same as calling the code once without a timeout. 在这种情况下,延迟为0的调用与一次调用代码而没有超时的情况相同。

setInterval is called every time the interval elapses, in your case all the time because the interval is 0. I think you want something more like: 每次经过间隔时都会调用setInterval ,因为间隔为0,因此在您的情况下始终都会调用setInterval

setInterval(function(){
  $('#foo').toggleFade(800);
}, 800);

My favorite timeout vs interval posting 我最喜欢的超时与间隔发布

The setTimeout method will do something after a period of time whereas the setInterval method will iteratively do something after X number of seconds (depending on the interval). setTimeout方法将在一段时间后执行某些操作,而setInterval方法将在X秒(取决于时间间隔)后迭代执行某些操作。

So to get setTimeout to do something iteratively, you would need to wrap the setTimeout within a loop (or similar). 因此,要让setTimeout迭代地执行某项操作,您需要将setTimeout包装在一个循环(或类似循环)中。

But based on what you are after - the setInterval method is the better of the two. 但是根据您的需求-setInterval方法是两者中较好的一种。

Check out: 查看:

http://www.w3schools.com/jsref/met_win_settimeout.asp http://www.w3schools.com/jsref/met_win_settimeout.asp

and

http://www.w3schools.com/jsref/met_win_setinterval.asp http://www.w3schools.com/jsref/met_win_setinterval.asp

Here is the defination of the two 这是两者的定义

setTimeout - The setTimeout function delays for a specified time period and then setTimeout- setTimeout函数延迟指定的时间段,然后
triggers execution of a specified function. 触发指定功能的执行。 Once the function is triggered the setTimeout 一旦函数触发,setTimeout
has finished. 已完成。 You can of course terminate the execution of the setTimeout before it 您当然可以在setTimeout之前终止执行
triggers the function by using the clearTimeout function. 通过使用clearTimeout函数来触发该函数。

setInterval - The setInterval function also delays for a specified time before setInterval- setInterval函数还会延迟指定的时间
triggering the execution of a specific function. 触发特定功能的执行。 Where it differs is that after 区别在于
triggering that function the command doesn't complete. 触发该功能的命令未完成。 Instead it waits for the 相反,它等待
specified time again and then triggers the function again and continues to repeat 再次指定时间,然后再次触发功能并继续重复
this process of triggering the function at the specified intervals until either the 以指定的时间间隔触发功能的过程,直到
web page is unloaded or the clearInterval function is called. 卸载网页或调用clearInterval函数。

setTimeout(func, millis) says "after millis has elapsed, I will invoke func". setTimeout(func,millis)说:“经过毫秒后,我将调用func”。 Your func is 你的功能是

function(){
    $("#foo").fadeOut().delay(800).fadeIn(800);
}

So after zero milliseconds elapse, your function gets called. 因此,经过零毫秒后,您的函数将被调用。 But there is nothing in your function that tells it to invoke setTimeout again. 但是您的函数中没有任何内容可以告诉它再次调用setTimeout。

Something like this will work: 这样的事情会起作用:

function my_func() {
    // do something
    setTimeout(my_func, 1000);
}

my_func();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM