Joe Di Stefano Joe Di Stefano - 3 months ago 12
Javascript Question

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?

Answer

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( t, counter )
  {
    return function()
    {
      if ( --t > 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 );