Wednesday, 6. August 2008
using timer to make listeners for mouseMove and click for the same component work without any conflict

Recently i had a problem of making mouseDown and click work on the same component as i was having difficulty to separate those two events. The problem was whenever i click it triggers the mouseDown first which i didn't want to happen. I was searching for a way to somehow distinguish between mouse down and click. As a click consists of mouse down and mouse up with very short time interval in general, i thought of deferring the action to be taken for mouseDown for an interval of time and see if mouseUp happens or not during that interval. If during that interval mouseUp occurs, then it was regarded as a click and click operation can be carried out. If not, then mouseDown's deferred action will come into act. So i used a timer to defer the action carried out in mouseDown for certain time say 300 ms. The code snippet is shown below:

private var interval:Number = 0;

private function mouseDownHandler(event:MouseEvent) : void {
	//one can store the event variable for later use in the deferred handler
	
	clearInterval(interval);
	interval = setInterval(deferredMouseDownHandler, 300);
}

private function deferredMouseDownHandler() : void {
	clearInterval(interval);
	//carry out the required actions
}

private function clickHandler(event:MouseEvent) : void {
	clearInterval(interval);
	//carry out the required action
}

setInterval is used to execute specified function at time interval specified. So one must be careful to use clearInterval in the deferred handler as well as the click handler so that the function is not re-executed. Here all the actions required to be performed in mouseDownHandler are moved to deferredMouseDownHandler. Now whenever mouseDown occurs then the system will wait for 300 ms as specified in here before deferredMouseDownHandler is executed and during that interval if click occurs then clickHandler will use clearInterval to stop the execution of deferredMouseDownHandler. If click does not occur withing 300 ms, then deferredMouseDownHandler will come into act.

What is achieved so far is whenever click occurs such that interval between mouse down and mouseup is less than 300 ms, mouseDownHandler will not be triggered first. However, When the mouse is down for more than 300 ms, then deferredMouseDownHandler will be executed and if whenever mouse is up, clickHandler will still come into act. So if you don't want to trigger the click after deferredMouseDownHandler is executed, few more efforts will be required. The whole working code is given below:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%" layout="vertical" verticalGap="5" horizontalAlign="center" verticalAlign="middle">
	<mx:Script>
		<![CDATA[
			private var interval:Number = 0;
			private var isMouseDown:Boolean = false;
			
			private function mouseDownHandler(event:MouseEvent) : void {
				clearInterval(interval);
				interval = setInterval(deferredMouseDownHandler, 300);
			}
			
			private function deferredMouseDownHandler() : void {
				clearInterval(interval);
				isMouseDown = true;
				actionStatus.text += "\nmouse down";
			}
			
			private function clickHandler(event:MouseEvent) : void {
				if(!isMouseDown){
					clearInterval(interval);
					actionStatus.text += "\nmouse click";
				}
				isMouseDown = false;
			}
		]]>
	</mx:Script>
	<mx:Label text="Click or Mouse Down on me" color="#000405" fontSize="12" mouseDown="mouseDownHandler(event)" click="clickHandler(event)" />
	<mx:Text width="147" id = "actionStatus"/>
</mx:Application>

I have used a flag isMouseDown which i set to true whenever the deferredMouseDownHandler is executed. Now when clickHandler is executed,it first checks this flag before carrying out its actions. This will help in completely isolating click actions from mouseDown actions.

This technique assumes that during click, the time interval between mouse up and mouse down is less than 300 ms. The interval can be adjusted as per the requirement.



Demo:





... comment