Interrupting a script.aculo.us event

A client wanted me to implement a drop down contact form that was triggered when the cursor hovered over a button in the site’s navigation. This was no problem, and I delivered some code using script.aculo.us‘s blind effect. A few hours later, the client contacted me and said that as he moved his cursor around the screen, he kept accidently triggering the contact form as the cursor moved through the element, and couldn’t I find a way to make the action a little more deliberate.

As far as I can tell, there is a way to delay a blind effect in script.aculo.us, but no way to stop the effect once the delay’s countdown has begun.

I searched around and came upon a w3schools JavaScript tutorial about timing events and the setTimeout() and clearTimeout() methods. This was exactly what I needed. By calling a function that started a countdown to the event rather than the event itself, and later calling a function that cancelled the countdown, it is possible to abort the drop down action if the mouse was moved out of the element within a specified time interval.

The code snippet below assumes you have links to the script.aculo.us and prototype libraries in place already. As the cursor enters the link, the startForm() function is called and a 500 ms timer begins. If the cursor moves out of the link, the stopForm() function is called, and the timer is cancelled. If stopForm() is called before the timer finishes counting, the effect never happens.

The client’s happy and I learned something useful.

The Code

<script type="text/javascript"><!--//--><![CDATA[//><!--
var t
function startForm() {
	t=setTimeout("Effect.toggle('contactform','blind')",500);
}
function stopForm() {
	clearTimeout(t);
}
//--><!]]></script>

A simple demonstration of how to implement this using inline JavaScript (a no-no).

<ul id="nav">
	<li><a href="#">a link</a></li>
	<li><a href="#">a link</a></li>
	<li><a href="#" onmouseover="startForm()" onmouseout="stopForm()">Contact Us</a></li>
</ul>
<div id="contactform">
        <!-- the form goes here -->
</div>