Question

I've created a slider which works on a timer along with next/prev arrows.

When an arrow is clicked I want to stop the auto timer then re-start x-time after the last click. Unfortunately what I have currently seems to que timers so if the arrow is clicked multiple times the auto timer restarts but moves really fast...

I can't seem to work it out - how to maintain just one setInterval and avoid them building up...

Any help greatly appreciated - code pasted below

    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);
        }
    });
Was it helpful?

Solution

You have to place the reference to the timout in the common scope of the click handlers, as shown below. When var is used in a new scope, the variable is declared again, in the local scope[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]: Illustrated explanation of local/global variables

In short, variables prefixed by the var keyword are declared again in the local scope. In JavaScript new scope can be created by surrounding a block by function() { .. }.

When a variable is requested, the engine first looks in the current (local) scope. If the variable is present, this variable is used.
Otherwise, the parent scope is examined, etc, etc, until the variable is found. If the variable is not found at the top (global scope), the following will happen:

  • In strict mode, a ReferenceError will be thrown.
  • When assigning, foo = 1, the variable will be declared at the global scope
    @Nitpicks: let not taken into account)
  • When reading: A ReferenceError will be thrown.
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)

OTHER TIPS

clearTimeout(timeout); will never work because "timeout" is not a global variable. You're defining it WITHIN the function.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top