1

我的页面上有多个元素,它们在使用javascript setInterval 的计时器上淡入淡出以将它们设置为运动。我把它们延迟了,所以它们稍微偏移一下,以创造一个很好的级联效果,但如果你让页面打开足够长的时间,它们都会互相赶上,时间就会变得一团糟(你必须把它留到几分钟)。

我在 CodePen 有一个丑陋的例子:http ://www.cdpn.io/wgqJj

同样,您必须让页面保持打开状态几分钟才能看到问题。如果页面上有更多项目(5 或 10),问题会变得更加明显。我还在几个 jQuery 照片旋转器插件中使用过这种效果,随着时间的推移,这个问题总是会出现。

对此有什么解释吗?

这是我正在使用的代码(我知道 javascript 可能更干净):

HTML:

<p id="one">First</p>
<p id="two">Second</p>
<p id="three">Third</p>

JavaScript:

$(document).ready(function() {
  var timer1 = setTimeout(startOne,1000);
  var timer2 = setTimeout(startTwo,2000);
  var timer3 = setTimeout(startThree,3000);
});

function startOne () {
  setInterval(flashOne,3000);
}

function startTwo () {
  setInterval(flashTwo,3000);
}

function startThree () {
  setInterval(flashThree,3000);
}

function flashOne () {
  $("#one").fadeTo("slow",0.4).fadeTo("slow",1.0);
}

function flashTwo () {
  $("#two").fadeTo("slow",0.4).fadeTo("slow",1.0);
}

function flashThree () {
  $("#three").fadeTo("slow",0.4).fadeTo("slow",1.0);
}
4

3 回答 3

1

和函数不能保证您的活动完全按计划进行setTimeout()setInterval()CPU 负载、其他浏览器任务和类似任务会影响您的计时器,因此它们对于您的用例来说不够可靠。

一个解决方案是异步事件(promises 或类似的)或使用 jQuery 提供的事件队列。这样,您既可以嵌套回调,也可以将它们排队,然后在队列中的最后一项到达时再次触发队列。.queue()API 文档页面有一个例子。

于 2013-08-12T20:50:56.190 回答
1

问题已经在这里得到解答。引用本主题中评分最高的答案:

它会在执行前至少等待 1000 毫秒,而不会恰好等待 1000 毫秒。

给出一个实际的答案,我会这样解决它:

$(function(){
  setTimeout(flashOne,1000);
});

function flashOne () {
  $("#one").fadeTo("slow",0.4).fadeTo("slow",1.0);
  setTimeout(flashTwo,1000);
}

function flashTwo () {
  $("#two").fadeTo("slow",0.4).fadeTo("slow",1.0);
  setTimeout(flashThree,1000);
}

function flashThree () {
  $("#three").fadeTo("slow",0.4).fadeTo("slow",1.0);
  setTimeout(flashOne,1000);
}

像这样,计时器不可能搞砸,因为它总是在之前的项目闪烁后延迟一秒钟。

于 2013-08-12T20:45:10.587 回答
1

考虑改用链式setInterval,因为这为浏览器提供了有保证的插槽。参考这个SO 帖子。.

目前您仅用于setInterval启动动画。从那里 jQuery 正在处理“振荡”。

从理论上讲,使用链式设置间隔应该向浏览器保证一个插槽。更重要的是,您可以在每个间隔将偏移量硬编码到代码中,而不是在开始时只写一次。

于 2013-08-12T20:44:39.600 回答