//
// try the timer factory
//
function timer ( callbacks, delay, fireNTimes ) {
timer._cb ||
( timer._cb = function () { return true; } );
return (function ( callbacks, delay, fireNTimes ) {
var
un,
timerState = {
'current-count' : 0,
'delay' : Math.abs( parseFloat( delay ) ) || 1000,
'repeat-count' : Math.abs( parseInt( fireNTimes ) ) || Number.POSITIVE_INFINITY,
'running' : false,
'interval' : un
},
callback = {
onTimer: callbacks.onTimer || timer._cb,
onStart: callbacks.onStart || timer._cb,
onStop : callbacks.onStop || timer._cb,
onEnd : callbacks.onEnd || timer._cb
};
return {
ctx: this,
startargs: [],
start: function ( /* callbacks_context, ...params */ ) {
var
that = this,
args = Array.prototype.slice.call( arguments, 1 );
( arguments[0] !== un ) && ( this.ctx = arguments[0] );
( args.length != 0 ) && ( this.startargs = args );
this.running() || (
timerState.running = true,
callback.onStart.apply( this.ctx, this.startargs ),
timerState['current-count'] += 1,
callback.onTimer.apply( this.ctx, this.startargs ),
( timerState['current-count'] == timerState['repeat-count'] ) &&
(
callback.onEnd.apply( this.ctx, this.startargs ),
( timerState["current-count"] = +( timerState.running = false ) ), true
) ||
( timerState.interval =
window.setInterval( function () {
timerState['current-count'] += 1;
callback.onTimer.apply( that.ctx, that.startargs );
( timerState['current-count'] == timerState['repeat-count'] ) &&
that.reset() &&
callback.onEnd.apply( that.ctx, that.startargs );
}, timerState.delay
)
)
);
return this;
},
stop: function () {
this.running() &&
(
window.clearInterval( timerState.interval ),
timerState.interval = un,
timerState.running = false,
callback.onStop.apply( this.ctx, this.startargs )
);
return this;
},
reset: function () {
return this.running() &&
( ! ( timerState["current-count"] = +( timerState.running = false ) ) ) &&
( window.clearInterval( timerState.interval ), true ) &&
( ( timerState.interval = un ), this );
},
currentCount: function () {
return timerState['current-count'];
},
delay: function () {
return timerState.delay;
},
repeatCount: function () {
return timerState['repeat-count'];
},
running: function () {
return timerState.running;
}
};
})( callbacks, delay, fireNTimes );
}
var
tm = timer(
{
onStart : function () { console.log( 'start:', 'this === ', this, arguments ); },
onTimer : function () { console.log( 'timer:', 'this === ', this, arguments ); },
onEnd : function () { console.log( 'done:', 'this === ', this, arguments ); },
onStop : function () { console.log( 'pause:', 'this === ', this, arguments ); }
},
2000
),
el = document.getElementById('btn1'),
o = { p1:'info' };
el.onmouseover = function () { tm.start( el, o ); };
el.onmouseout = function () { tm.stop(); };
//
//
// start: this === <button id="btn1"> [Object { p1="info"}]
// timer: this === <button id="btn1"> [Object { p1="info"}]
// timer: this === <button id="btn1"> [Object { p1="info"}]
// timer: this === <button id="btn1"> [Object { p1="info"}]
// pause: this === <button id="btn1"> [Object { p1="info"}]
//
// etc...
//
//