首页 > 解决方案 > 切换标签后 setInterval() 行为怪异

问题描述

我使用 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();
});

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

标签: javascriptjquerysetintervaleffects

解决方案


当标签没有焦点(以及许多其他奇数游戏,例如在焦点返回时会加速)时,计时器会被抛弃,因此您setInterval和您的您setTimeout可能会失去同步。

相反,只需使用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);
}

和/或您可能会考虑可以触发的回调,fadeOut特别fadeIn是在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;

推荐阅读