Почему setTimeout “ставит в очередь” обратные вызовы при вызове stopTimeout?
-
27-10-2019 - |
Вопрос
Я создал слайдер, который работает по таймеру вместе со стрелками next / prev.
При нажатии на стрелку я хочу остановить автоматический таймер, а затем повторно запустить x-time после последнего нажатия.К сожалению, то, что у меня есть в настоящее время, похоже, требует установки таймеров, поэтому, если щелкнуть стрелку несколько раз, автоматический таймер перезапускается, но движется очень быстро...
Кажется, я не могу разобраться в этом - как поддерживать только один setInterval и избегать их накопления...
Любая помощь с благодарностью - код вставлен ниже
var int = setInterval(back, autoTimerTime);
//down arrow
$('.arrow-down').click(function(){
if (!$('ul.as-thumbs').is(':animated')) {
back();
clearInterval(int);
clearTimeout(timeout);
var timeout = setTimeout(function() {
var int = setInterval(back, autoTimerTime);
}, 8000);
}
});
Решение
Вы должны поместить ссылку на timout
в общей сфере применения click
обработчики, как показано ниже.Когда var
используется в новой области видимости, переменная объявляется снова, в локальной области видимости[1].
var int = setInterval(back, autoTimerTime);
var timeout; // This variable is now shared by all $('.arrow-down').click funcs
//down arrow
$('.arrow-down').click(function(){
if (!$('ul.as-thumbs').is(':animated')) {
back();
clearInterval(int);
clearTimeout(timeout);
timeout = setTimeout(function() {
// Removed `var` too
int = setInterval(back, autoTimerTime);
}, 8000);
}
});
[1]:Иллюстрированное объяснение локальных / глобальных переменных
Короче говоря, переменные с префиксом var
ключевые слова снова объявляются в локальной области видимости.В JavaScript новая область видимости может быть создана путем окружения блока function() { .. }
.
Когда запрашивается переменная, движок сначала просматривает текущую (локальную) область видимости.Если переменная присутствует, используется эта переменная.
В противном случае проверяется родительская область видимости и т.д., и т.д., пока переменная не будет найдена.Если переменная не найдена в верхней части (глобальная область видимости), произойдет следующее:
- В строгом режиме a
ReferenceError
будет выброшен. - При назначении,
foo = 1
, переменная будет объявлена в глобальной области видимости
@Придирки:let
не принимается во внимание) - При чтении:A
ReferenceError
будет выброшен.
var int = 1, timeout = 2, homeless = 3;
function click() {
var timeout = 1;
homeless = 4;
timeout = function() {
var int = 2;
}
}
click();
Variables in the global scope:
- int (declared using var, inititalized at 1)
- timeout (declared using var, inititalized at 2)
- homeless(declared using var, initialized at 3)
--- New scope of: function click()
- No declaratation of `int`, so if used, `int` refers to the global `int`
- Global var: homeless (assigned 4)
- Local var: timeout (declared using var, init at 1)
- Local var: timeout (assigned anonymou function())
--- New scope of: function()
- Local var: int (declared using var, init at 1)
- Accessible vars from parent scope: timeout
- Accessible vars from global scope: homeless, int
(Note that the global `timeout` var is unreachable, because it
has been redeclared at the parent scope)
Другие советы
clearTimeout(timeout);
никогда не будет работать, потому что «тайм -аут» не является глобальной переменной. Вы определяете это в функции.