Search code examples
javascripttimersetinterval

Changing the interval of SetInterval while it's running


I have written a javascript function that uses setInterval to manipulate a string every tenth of a second for a certain number of iterations.

function timer() {
    var section = document.getElementById('txt').value;
    var len = section.length;
    var rands = new Array();

    for (i=0; i<len; i++) {
        rands.push(Math.floor(Math.random()*len));
    };

    var counter = 0
    var interval = setInterval(function() {
        var letters = section.split('');
        for (j=0; j < len; j++) {
            if (counter < rands[j]) {
                letters[j] = Math.floor(Math.random()*9);
            };
        };
        document.getElementById('txt').value = letters.join('');
        counter++

        if (counter > rands.max()) {
            clearInterval(interval);
        }
    }, 100);
};

Instead of having the interval set at a specific number, I would like to update it every time it runs, based on a counter. So instead of:

var interval = setInterval(function() { ... }, 100);

It would be something like:

var interval = setInterval(function() { ... }, 10*counter);

Unfortunately, that did not work. It seemed like "10*counter" equals 0.

So, how can I adjust the interval every time the anonymous function runs?


Solution

  • Use setTimeout() instead. The callback would then be responsible for firing the next timeout, at which point you can increase or otherwise manipulate the timing.

    EDIT

    Here's a generic function you can use to apply a "decelerating" timeout for ANY function call.

    function setDeceleratingTimeout(callback, factor, times)
    {
        var internalCallback = function(tick, counter) {
            return function() {
                if (--tick >= 0) {
                    window.setTimeout(internalCallback, ++counter * factor);
                    callback();
                }
            }
        }(times, 0);
    
        window.setTimeout(internalCallback, factor);
    };
    
    // console.log() requires firebug    
    setDeceleratingTimeout(function(){ console.log('hi'); }, 10, 10);
    setDeceleratingTimeout(function(){ console.log('bye'); }, 100, 10);