So, yesterday I was working on the UI for our category menus and needed a delay before displaying the menus.
Basically, I wanted to only show the dropdown menus if the user pauses the cursor over the menu in question. To do this, I needed a timer object that I could start when the user first places the cursor over the menu title and cancel if they move on to quickly.
If you’ve ever used the setTimeout() and clearTimeout() functions that Javascript provides, you know that they don’t always work as advertised. Especially when many are called very rapidly (as in the case of the user moving the cursor from one side of the screen to the other). Using just these functions gave us some weird behavior (i.e. menus displaying when they shouldn’t).
To solve the problems we encountered, I created a timer object (sorely lacking in Javascript) that tracks its state so that it more reliably executes and cancels.
Below is the code for the object (requires prototype):
var timer = function(delay, callback){
this.isRunning = false;
this.hndl = null;
this.delay = 0;
this.callback = null;
this.start = function(){
if(!this.isRunning){
this.hndl = setTimeout(this.callBackFunc.bind(this), this.delay);
this.isRunning = true;
}
};
this.stop = function(){
if(this.isRunning){
clearTimeout(this.hndl);
this.hndl = null;
this.isRunning = false;
}
};
this.setDelay = function(d){
this.delay = d * 1000;
};
this.setCallback = function(c){
this.callback = c;
};
this.callBackFunc = function(){
if(this.isRunning){
this.isRunning = false;
this.hndl = null;
eval(this.callback);
}
};
this.setCallback(callback);
this.setDelay(delay);
};
You use it by creating a new instance of timer and calling the instance’s start() method for every action you want to delay.
Below are Parameter descriptions:
- delay: how long to wait before running the callback code (in seconds)
- callback: a string of Javascript code to execute after the delay
Example:
<div onmouseover="myTimer = new timer(0.5, 'myfunction(5, 6, 7)'); myTimer.start();" onmouseout="if(myTimer){myTimer.stop();}">
Some content
</div>
The above code will start the timer when the user places the mouse over the div and cancel the action if the user moves the mouse out of the div before the timer has fired.
