The following code is supposed to measure how long a key (or more keys) was pressed.
var output = document.getElementById('output'),
pressed = {};
window.onkeydown = function(e) {
if ( pressed[e] ) return;
pressed[e] = e.timeStamp;
};
window.onkeyup = function(e) {
if ( !pressed[e] ) return;
var duration = ( e.timeStamp - pressed[e] ) / 1000;
var today = new Date();
var date = today.getDate()+'-'+(today.getMonth()+1)+'-'+today.getFullYear();
var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
var dateTime = date+' '+time;
output.innerHTML += dateTime + ' - Key(s) pressed for ' + duration + ' seconds</p>';
pressed[e] = 0;
}
<div id="output"></div>
Is there any way to change the window.onkeyup function so that it makes the output log only when ALL keys are released?
Example:
10:00:00 - I press A and hold it
10:00:05 - I press B and hold it
10:00:20 - I press C and hold it
10:00:22 - I release A
10:00:24 - I release B
10:00:30 - I release C
Current code output:
26-2-2021 10:00:22 - Key(s) pressed for 22 seconds
26-2-2021 10:00:24 - Key(s) pressed for 2 seconds
26-2-2021 10:00:30 - Key(s) pressed for 6 seconds
Expected output:
26-2-2021 10:00:30 - Key(s) pressed for 30 seconds
Thank you for your help.
First of all, you should do pressed[e.code]
, not pressed[e]
, as this e
object value will just stringify to [object KeyboardEvent]
, and so you assign to just one and the same property, on each keyboard event.
To only report when all keys are up, keep track of a count and of the time the first key was pressed:
var output = document.getElementById('output'),
pressed = {},
keyDownCount = 0,
keyDownTime = 0;
window.onkeydown = function(e) {
if ( pressed[e.code] ) return;
pressed[e.code] = true;
if (!keyDownCount) keyDownTime = e.timeStamp;
keyDownCount++;
};
window.onkeyup = function(e) {
if ( !pressed[e.code] ) return;
pressed[e.code] = false;
keyDownCount--;
if (keyDownCount) return;
var duration = ( e.timeStamp - keyDownTime ) / 1000;
var today = new Date();
var date = today.getDate()+'-'+(today.getMonth()+1)+'-'+today.getFullYear();
var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
var dateTime = (date+' '+time).replace(/\b\d\b/g, "0$&");
output.innerHTML += dateTime + ' - Key(s) pressed for ' + duration + ' seconds</p>';
}
<div id="output"></div>
Note that this is not completely bullet proof. If someone focusses another window and changes which keys are pressed before returning, these changes will not fire the events.