Reputation: 1449
I am implementing an idle timeout functionality for my website. I want to reset the idle timeout whenever the user interacts with the page, which I want to implement as "the user clicks anywhere on the page" or "the user types a key".
The following code works:
window.addEventListener('click', resetTimeout);
window.addEventListener('keydown', resetTimeout);
Unfortunately it detects modifier keys (alt, shift, ctrl, meta). I don't want to reset the timeout in these cases. For example, when the user alt+tab's to another window, the alt key resets the timeout.
An alternative to keydown
is keypress
, however, it is marked as deprecated. Is there an alternative for keypress
, specifically for the situation I am describing?
Upvotes: 4
Views: 2876
Reputation: 14133
I came here looking for an answer but was not happy with having to maintain a list of exclusions so I solved this by checking the length of the key name.
window.addEventListener('keydown', resetTimeout);
function resetTimeout(args) {
if (args.key.length === 1) {
// 'a', 'A', '1', '.', '%' etc
} else {
// 'Alt', 'Control', 'Shift', 'Escape', 'Backspace' etc
}
}
You can also use the next trick to isolate modifier keys from any other key. Thanks to @mikeypie for the suggestion.
function resetTimeout(args) {
if (args.key.length === 1 || args.key === args.code) {
// 'a', 'A', '1', '.', '%', 'Escape', 'Backspace' etc
} else {
// 'Alt', 'Control', 'Shift'
}
}
This works because the args.code
includes Left
or Right
for modifier keys,
e.g. when left Shift is pressed:
args.key: "Shift"
args.code: "ShiftLeft"
Upvotes: 3
Reputation: 50914
You'd need a variable to keep a true/false which tells you whether an ignored key is being held down, and if it is, then you can ignore all keydown events which would reset your timer. When your ignored key is released, you can then listen for keydown events.
Here is a small demo:
const display = document.getElementById('status');
let idleTime = 0;
const timer_cb = _ => {
if(idleTime > 5) {
display.innerText = "You are now idle";
clearInterval(timer);
} else {
display.innerText = "You have been inactive for: " + idleTime +" seconds";
idleTime++;
}
}
let timer = setInterval(timer_cb, 1000);
const ignoreKeys = new Set(['Meta', 'Control', 'Shift', 'Alt']);
let ignore = false;
const resetTimeout = ({key}) => {
ignore = ignore || ignoreKeys.has(key);
if(!ignore) {
idleTime = 0;
timer_cb();
clearInterval(timer);
timer = setInterval(timer_cb, 1000);
}
};
const acknowledge = ({key}) => {
ignore = !!(ignore ^ ignoreKeys.has(key));
}
window.addEventListener('click', resetTimeout);
window.addEventListener('keydown', resetTimeout);
window.addEventListener('keyup', acknowledge);
timer_cb();
<span id="status"></span>
Upvotes: 1
Reputation: 163
note to excludedKeys you can add all keys you don't want. You can search for them here: https://www.w3.org/TR/uievents-key/
let excludedKeys = ["Alt"];
window.addEventListener('keydown', e => {
if(!excludedKeys.includes(e.key)) resetTimeout();
});
Upvotes: 2
Reputation: 845
Add function and check for the command keys as follow:
document.addEventListener("keydown", function(event) {
event.preventDefault();
const key = event.keyCode; //You can also use event.key to get the text value. e.g. "Alt", "Ctrl"
if(key != 17 && key != 18) //Alt and Ctrl keys. key should not 17 as well as 18 then resetTimeOut.
{
resetTimeout();
}
});
If you want to use .key then you can use string and check the pressed key is present in that string or not.
document.addEventListener("keydown", function(event) {
event.preventDefault();
const key = event.key
if(! "Alt,Control,Tab".split(",").includes(key))
{
resetTimeout();
}
});
Upvotes: -2