На ум приходит несколько идей:
Идея # 1
Вы можете сделать так, чтобы короткий взрыв был идемпотентным .Например, вы можете сказать:
function now() {
return (new Date()).getTime();
}
var autopagerInterval = 8000;
function startAutopager() {
var startImage = getCurrentImageNumber();
var startTime = now();
var autopager = setInterval(
function() {
var timeSinceStart = now() - startTime();
var targetImage = getCurrentImageNumber + Math.ceil(timeSinceStart/autopagerInterval);
if (getCurrentImageNumber() != targetImage)
setImageNumber(targetImage); // trigger animation, etc.
},
autopagerInterval
);
return autopager;
}
Таким образом, даже если функция выполняется 1000 раз, она все равно будет работать всего за несколько миллисекунд и анимироваться только один раз.
note: Если пользователь покидает страницу и возвращается, она будет прокручена.Вероятно, это не то, чего хочет оригинальный постер, но я оставляю это решение, поскольку иногда это то, что вы хотите.
Идея # 2
Еще один способ добавить идемпотентность (пока ещесохранение вашей функции nextImage()
и отсутствие ее прокрутки вниз страницы) означало бы, что функция установила блокировку мьютекса, которая исчезает через секунду (очищается другим таймаутом).Таким образом, даже если функция setInterval была вызвана 1000 раз, будет запущен только первый экземпляр, а остальные ничего не сделают.
var locked = false;
var autopager = window.setInterval(function(){
if (!locked) {
locked = true;
window.setTimeout(function(){
locked=false;
}, 1000);
nextImage();
}
}, 8000);
edit: это может не сработать, см. Ниже
Идея # 3
Я попробовал следующий тест:
function f() {
console.log((new Date()) + window.focus());
window.setTimeout(f, 1000);
}
f();
Кажется, это указывает на то, что функция вызывается каждую секунду.Это странно ... но я думаю, что это означает, что обратные вызовы вызывают , но рендерер отказывается обновлять страницу любым графическим способом, пока вкладка не сфокусирована,задержка всех операций до тех пор, пока пользователь не вернется, но операции продолжают накапливаться.
Также функция window.focus()
не сообщает, имеет ли окно фокус;он дает фокус на окно и, таким образом, не имеет значения.
Вероятно, нам нужно следующее: Как определить, фокусируется ли вкладка или нет в Chrome с помощью Javascript? - вы можетесбросьте интервал, когда окно теряет фокус (размытие), и сбросьте его, когда оно получает фокус.