Wednesday 2 May 2007

Javascript Timer object for active pages/tabs

Sometimes you want to fire an event on a webpage with a certain delay. There are couple ways to do that. Today I'm gonna present a JS Timer object, which waits a given amount of seconds after it's creation till it raises an alert. In addition out timer will work only when the page is active. If it looses a focus the timer stops. It resumes when it gains it back. Here is my code with some comments:
var TimerJob = Class.create();
TimerJob.prototype = {

/*PeriodicalExecuter*/ pe : null,

//numbers of seconds to wait
/*int*/ sec : 600,

//flag set after countdown finishes
/*bool*/ finished : false,

// Initializes the timer
initialize : function(){
this.pe = new PeriodicalExecuter(this.execute.bind(this),1);
window.onblur = this.abort.bindAsEventListener(this);
},

// Stops the timer countdown if page/tab looses focus
// Handles window.onblur event
abort : function(evt){
$('informer').innerHTML = "abort";
window.onblur = '';
window.onfocus = this.resume.bindAsEventListener(this);
this.pe.stop();
},

// Resumes the timer countdown when page/tab gains focus
// Handles window.onfocus event
resume : function(evt){
if(this.finished){
window.onfocus = '';
window.onblur = '';
}else{
this.pe = new PeriodicalExecuter(this.execute.bind(this),1);
window.onfocus = '';
window.onblur = this.abort.bindAsEventListener(this);
}

},

// Restarts the timer countdown
restart : function(){
this.pe.stop();
this.pe = new PeriodicalExecuter(this.execute.bind(this),1);
window.onblur = this.abort.bindAsEventListener(this);
},

// Action executed by timer each second
execute : function(_pe){

$('informer').innerHTML = this.sec;
this.sec--;
if(this.sec <= 0){
this.pe.stop();

alert("It is time!!!");

this.finished = true;
window.onblur = '';
window.onhelp = '';
}
},
}
The code above uses protoype.js library, which I already mentioned several times. Let me explain a little bit how it works. Initialize() method is a constructor, which starts the countdown. PeriodicalExecuter is an object from prototype.js library, which name explains everything :) Each second execute() method is invoked, which sets the number of seconds left in the page element identified by id 'informer'. Every time the page looses it focus (window.onblur) the abort() method is invoked which stops the countdown. When it gains focus back (window.focus) the resume() method is invoked. When the counter reaches 0 alert is raised and we don't care about focus or other stuff any more :)

Any questions?

PS. The code has been tested on Opera 9.2 and FF 1.5 (Ubuntu Dapper Drake)

1 comment:

daphotons said...

Hi Filip !

Thank you for the above code !

I want to save the time spent on each tab on a page into a database using php ... Would be of great help