javascript setInterval没有保留它's时机合适

javascript setInterval not keeping it's timing properly

本文关键字:时机 setInterval 有保留 javascript      更新时间:2023-09-26

我的页面上有多个元素,它们在计时器上淡入淡出,使用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);
}

这里已经回答了问题。引用本主题中评分最高的答案:

在执行之前,它将等待至少1000MS,而不会等待完全1000MS。

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

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

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

考虑使用链式setInterval,因为这会为浏览器提供一个有保证的插槽。参考此SO帖子。。

目前,您仅使用setInterval来启动动画。jQuery从那里开始处理"振荡"。

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

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

解决方案是异步事件(promise或类似事件)或使用jQuery提供的事件队列。这样,您可以嵌套回调,或者将它们排队,然后在队列中的最后一个项目命中后再次启动队列。.queue() API文档页面提供了一个示例。