Почему setTimeout “ставит в очередь” обратные вызовы при вызове stopTimeout?

StackOverflow https://stackoverflow.com/questions/8840657

Вопрос

Я создал слайдер, который работает по таймеру вместе со стрелками 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); никогда не будет работать, потому что «тайм -аут» не является глобальной переменной. Вы определяете это в функции.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top