Skip to content

Instantly share code, notes, and snippets.

@runspired
Last active December 15, 2015 16:19
Show Gist options
  • Save runspired/5288584 to your computer and use it in GitHub Desktop.
Save runspired/5288584 to your computer and use it in GitHub Desktop.
setInterval() and setTimeout() don't fit all use cases. Additionally the last few releases of Firefox have sped up the interval to almost 50% the defined value e.g. `setTimeout('foo,5000);` will execute in 2500ms This provides a firefox shunt as well as allowing for the interval's delay to be adjusted, paused, and restarted
function complexInterval = function( fn , t ) {
var _delay = t? parseInt(t) : 0
, callback = fn
//stores the time of last callback execution for play/pause behavior and firefox shunt
, lastExecution = (new Date()).getTime()
//shunt for firefox, which executes setTimeout up to 50% early
, checkExecution = function(){ var time = (new Date()).getTime() - lastExecution; if (time >= _delay) return true; timeout = setTimeout( (function(){ once(); }), time ); }
//execute the callback and setup the next one
, once = function(){ if( checkExecution() ){ callback(); lastExecution = (new Date()).getTime(); timeout = setTimeout( (function(){ once(); }), _delay );}}
//initiate the callback loop
, timeout = setTimeout( (function(){ once(); }) , _delay )
, timeElapsed = 0
;
Object.defineProperty( this , 'delay' , {
get : function() { return _delay; }
, set : function(b) { _delay = parseInt(v); }
});
this.reset = function(){
if( timeout !== false ) {
clearTimeout(timeout);
timeout = false; //sometimes unless I explicitly set it to false it doesn't clear.
timeout = setTimeout( (function(){ once(); }) , _delay );
}
};
this.pause = function(){
if( timeout !== false ) {
clearTimeout( timeout );
timeout = false;
timeElapsed = (new Date()).getTime() - lastExecution;
}
};
this.play = function(){
//reset lastExecution so it's not far in the past
lastExecution = (new Date()).getTime() - Math.max(0, _delay - timeElapsed);
timeout = setTimeout( (function(){ once(); }) , Math.max(0, _delay - timeElapsed) );
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment