MouseDown occurs when the user presses the mouse button; MouseUp occurs when the user releases the mouse button.
Note: This differs from the click event in that click is fired after a full click action occurs; that is, the mouse button is pressed and released while the pointer remains inside the same element. mousedown is fired the moment the button is initially pressed.
Mouseup is always firing before click, despite this order.
The onmousedown event occurs when a user presses a mouse button over an element. Tip: The order of events related to the onmousedown event (for the left/middle mouse button): onmousedown. onmouseup.
You could create a closure to share two variables, one to store the start time and other for the end time, then in the mouseup event, get the difference:
(function () {
var element = document.getElementById('element'),
start, end;
element.onmousedown = function () {
start = +new Date(); // get unix-timestamp in milliseconds
};
element.onmouseup = function () {
end = +new Date();
var diff = end - start; // time difference in milliseconds
};
})();
Check this working example.
.timeStamp
property of the first event from the .timeStamp
property of the second event. new Date()
or calling Date.now()
inside its handler.const button = document.getElementById("button");
let mousedownTime;
button.addEventListener('mousedown', () => {
mousedownTime = new Date().getTime();
});
button.addEventListener('mouseup', function () {
const mouseupTime = new Date().getTime(),
timeDifference = mouseupTime - mousedownTime;
alert(`Button held down for ${timeDifference}ms`);
});
<button id="button">Click Me</button>
This is a much more subtle problem than other answers here give it credit for being.
The approach proposed by CMS's answer - of getting the time inside each handler by creating a new Date()
and then subtracting these times from each other - has the potential to be grossly inaccurate. The problem with this approach is that you're not comparing the times at which the events occurred, you're comparing the times at which their handlers fired.
The article linked to by the question asker - John Resig's How JavaScript Timers Work - is relevant to understanding the problem here. JavaScript execution is single threaded, and whenever something outside of JavaScript triggers some JavaScript execution - whether it's a timeout firing, an event occurring, or a script loading - that JavaScript gets added to a queue of callbacks waiting to fire, which get executed sequentially.
This leads to a couple of ways that our attempt to calculate the time between events can get horribly screwed up if we try to calculate it based upon the times that the handlers run. Consider the following two scenarios:
First scenarioWhat happens next? The computationally expensive JavaScript finishes running, and then both event handlers fire in rapid succession. Consequently, if you are timing the events by getting the current time when the handler fires, you will wrongly calculate the time between the events to be close to 0 milliseconds.
Second scenarioWhat happens next? This time, of course, we will wrongly calculate the time between events as being approximately 1 second, because the second handler's execution gets delayed.
You can see this in action here:
const button = document.getElementById("button");
let mousedownTime;
button.addEventListener('mousedown', function () {
mousedownTime = new Date().getTime();
document.getElementById("mousedown-time").innerHTML = mousedownTime;
document.getElementById("time-difference").innerHTML = '';
hotSleep();
});
button.addEventListener('mouseup', function () {
const mouseupTime = new Date().getTime(),
timeDifference = mouseupTime - mousedownTime;
document.getElementById("mouseup-time").innerHTML = mouseupTime;
document.getElementById("time-difference").innerHTML = timeDifference;
});
/**
* Hot-sleeps for 1 second when called.
*
* In a real life scenario, this might be some expensive numerical
* computation, or some DOM manipulation code.
*/
function hotSleep () {
const startTime = new Date().getTime();
while (new Date().getTime() < startTime+1000) {}
}
<button id="button">Click Me</button>
<div>
Time of last mousedown: <span id="mousedown-time"></span>
</div>
<div>
Time of last mouseup: <span id="mouseup-time"></span>
</div>
<div>
Time between events: <span id="time-difference"></span>
</div>
Just click the button and observe that the calculated time difference between mousedown and mouseup is always roughly 1000ms.
What can we do to stop this? Well, ideally, we want a way of getting the actual time an event occurred, not merely the time its handler fired. Does the DOM API offer us such a thing?
In modern browsers, yes. Events have a .timeStamp
property, which, nowadays, should provide the time the event occurred rather than the time the handler fired. (This wasn't true in the past; when I first wrote this answer, only Firefox implemented this properly and other browsers would return the time the handler fired. Thankfully, everyone now implements this correctly.)
Below, then, is a modified version of the example with the hot-sleep from above. The only change is that the time that events occurred is determined using the events' .timestamp
property - which is enough to mean that we now compute the duration of the click correctly.
const button = document.getElementById("button");
let mousedownTime;
button.addEventListener('mousedown', e => {
mousedownTime = e.timeStamp;
document.getElementById("mousedown-time").innerHTML = mousedownTime;
document.getElementById("time-difference").innerHTML = '';
hotSleep();
});
button.addEventListener('mouseup', e => {
const mouseupTime = e.timeStamp,
timeDifference = mouseupTime - mousedownTime;
document.getElementById("mouseup-time").innerHTML = mouseupTime;
document.getElementById("time-difference").innerHTML = timeDifference;
});
/**
* Hot-sleeps for 1 second when called.
*
* In a real life scenario, this might be some expensive numerical
* computation, or some DOM manipulation code.
*/
function hotSleep () {
const startTime = new Date().getTime();
while (new Date().getTime() < startTime+1000) {}
}
<button id="button">Click Me</button>
<div>
Time of last mousedown: <span id="mousedown-time"></span>
</div>
<div>
Time of last mouseup: <span id="mouseup-time"></span>
</div>
<div>
Time between events: <span id="time-difference"></span>
</div>
Since the other links seem to be broken now, at least on chrome, here's a simple working demo:
var startTime;
window.startTimer = function() {
startTime = new Date();
}
window.reportTime = function() {
alert(new Date() - startTime)
}
<button onmousedown="startTimer()" onmouseup="reportTime()">Measure click time</button>
When onmousedown is fired you can hang an onmouseup event on window. This will allow to avoid unnecessary closures.
el.onmousedown = function () {
var time = new Date(); //time in milliseconds
window.onmouseup=function(){
var diff=new Date()-time;
window.onmouseup=null;
}
};
check result here: http://jsbin.com/uneqo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With