setInterval () действует странно после переключения вкладок - PullRequest
0 голосов
/ 23 октября 2018

Я создал эффект, используя javascript для отображения топовых категорий в моем проекте.

enter image description here

Как вы можете видеть на изображении выше, он работаетпрекрасно.Но после бега в течение некоторого времени;Если пользователь покидает эту страницу и переключается на другую вкладку и через некоторое время возвращается к ней, он начинает действовать странно.

enter image description here

Ниже приведенакод, который я использую для создания этого эффекта.

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

Что вызывает эту проблему?Чего мне не хватает?

Ответы [ 2 ]

0 голосов
/ 23 октября 2018

Интервал 3000 мс может работать быстрее, чем тайм-аут 400 мс, поскольку браузер пытается синхронизировать интервал после возврата на вкладку.Чтобы решить эту проблему, вы можете использовать отложенный цикл, например:

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

 (async function() {
    while(true) {
      hideCurrent();
      await timer(400);
      showNext();
      await timer(2600);
   }
 })()
0 голосов
/ 23 октября 2018

Таймеры возвращаются назад, когда вкладка не имеет фокуса (и многих других странных игр, таких как ускорение, когда фокус возвращается), поэтому ваши 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;
...