【问题标题】:setInterval() acts weird after switching tabs切换标签后 setInterval() 行为怪异
【发布时间】:2018-10-23 13:52:01
【问题描述】:

我使用 javascript 创建了一个效果来显示项目中的热门类别。

如上图所示,它运行良好。但是跑了一段时间后;如果用户离开此页面并切换到另一个选项卡并在一段时间后返回此页面,那么它就会开始表现得很奇怪。

下面是我用来实现这个效果的代码。

var curCat = 0;
var cats = [
  "<a href='/search/?cat=1'>Animals</a>",
  "<a href='/search/?cat=2'>Graffiti</a>",
  "<a href='/search/?cat=3'>Figures</a>",
  "<a href='/search/?cat=6'>Landscape</a>",
  "<a href='/search/?cat=7'>Portrait</a>",
  "<a href='/search/?cat=9'>Other</a>"
];

function catSlider() {
  $(catDisplay).html(cats[curCat]);
  $(catDisplay).fadeIn();
  setInterval(function() {
    $(catDisplay).fadeOut();
    setTimeout(function() {
      if (++curCat >= cats.length) {
        curCat = 0;
      }
      $(catDisplay).html(cats[curCat]);
      $(catDisplay).fadeIn();
    }, 400);
  }, 3000);
}

$(document).ready(function() {
  catSlider();
});

是什么导致了这个问题?我错过了什么?

【问题讨论】:

  • 那是因为你在间隔中超时了。
  • @JᴀʏMᴇᴇ 我需要超时来保持 2 个显示项目之间的间隙
  • 超时 + 间隔 = 为什么?
  • @epascarello - 对我来说很有意义。每三秒淡出,0.4秒后淡入;冲洗,重复。如果不是节流阀就好了。
  • 超时的 400 与 fadeOut() 的默认动画时间相匹配 - 所以它是淡出,完成后,设置值并淡入 - 这就是淡出回调的​​用途。

标签: javascript jquery setinterval effects


【解决方案1】:
当标签没有焦点时(以及许多其他奇怪游戏,例如在焦点返回时加速),所以你的@ 987654321 >

相反,只需使用setTimeout,其中每个动作(淡出和淡入)都会触发下一个动作:

function catSlider() {
  $(catDisplay).html(cats[curCat]);
  $(catDisplay).fadeIn();
  function fadeOut() {
    $(catDisplay).fadeOut();
    setTimeout(fadeIn, 400);
  }
  function fadeIn() {
    if (++curCat >= cats.length) {
      curCat = 0;
    }
    $(catDisplay).html(cats[curCat]);
    $(catDisplay).fadeIn();
    setTimeout(fadeOut, 3000);
  }
  setTimeout(fadeOut, 3000);
}

并且/或者您可能会考虑fadeOutfadeIn 可以触发的回调,特别是在fadeOut 上:

function catSlider() {
  $(catDisplay).html(cats[curCat]);
  $(catDisplay).fadeIn();
  function fadeOut() {
    $(catDisplay).fadeOut(fadeIn);  // ***
  }
  function fadeIn() {
    if (++curCat >= cats.length) {
      curCat = 0;
    }
    $(catDisplay).html(cats[curCat]);
    $(catDisplay).fadeIn();
    setTimeout(fadeOut, 3000);
  }
  setTimeout(fadeOut, 3000);
}

旁注:如果你喜欢,你可以替换

if (++curCat >= cats.length) {
  curCat = 0;
}

curCat = (curCat + 1) % cats.length;

【讨论】:

  • 非常感谢。从来不知道有油门后退问题。
  • @RoshanaPitigala - 浏览器在过去几年才真正开始显着做这件事。 :-) 我认为在那之前有一个完全暂停计时器,但不是他们现在的复杂行为。
【解决方案2】:

3000 毫秒间隔可能比 400 毫秒超时运行得更快,因为浏览器会在您返回选项卡后尝试使间隔同步。要解决此问题,您可以使用延迟循环,例如:

 const timer = ms => new Promise(res => setTimeout(res, ms));

 (async function() {
    while(true) {
      hideCurrent();
      await timer(400);
      showNext();
      await timer(2600);
   }
 })()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多