I need to have some functionality in my web app where a specific action occurs when the user clicks and holds on an element. Think of it like the long press on Android.
I have my div:
<div id="myDiv"
onmousedown="press()"
onmouseup="cancel()"
onmouseout="cancel()"
onmousemove="cancel()">Long Click Me</div>
and my javascript:
var down = false;
function press()
{
down = true;
setTimeout(function() { action(); }, 1500);
}
function cancel()
{
down = false; // this doesn't happen when user moves off div while holding mouse down!
}
function action()
{
if (!down)
return; // if the flag is FALSE then do nothing.
alert("Success!");
down = false;
}
This works as long as all I do is press and hold on the element. I have the onmouseout and onmousemove events to call cancel() because I want the user to have the option to change their mind and move the mouse off the element before action() starts.
Unfortunately, it seems that my code does not do this.
In fact, if the use clicks down for a moment, moves the mouse off the div and releases before the 1.5 sec then action() won’t bail out as expected.
Edit: Thanks for your input everyone but it turns out I’m just a little bit special and didn’t see that I forgot a capital letter in my HTML in my onmouseout. The sample code I gave above should work exactly as expected.
Of course action() is still called. You didn’t actually cancel the
setTimeout()function. I would suspect that maybe in your real code, you have a scoping issue and maybe aren’t testing the same version of thedonevariable that you think you are.A better way than using the
downflag would be to keep track of the return value fromsetTimeout()and actually cancel the timer in thecancel()function. Then,action()will never fire when you don’t want it to. I think it’s also technically a more correct behavior when you mouseout to cancel any chance of the timer firing.Also, there is no such thing as:
in javascript. It would have to be:
I would recommend this code: