Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Detecting if a user has stopped interacting with a web view for a certain time
I am interested in finding out all the aspects I need to cover in order to correctly assess if a user has stopped interacting with a web page. So far, I found the following:
- Idle Detection API - this seems to do most of the work for idle detection. However, it requires user permission
- Detect page/tab/browser close - this is covered by beforeunload event
- Heartbeat function - this is useful when idle detection is not allowed or supported. Basic example here.
Is there anything else I should check for? I am currently focused on using this in an Angular SPA, but I guess that it is less relevant.
1 answer
The weakness of responding to idle state is that the app might be closed before the idle state is reached, and that a closing app might no longer be able to communicate with the outside world. Saving to local storage rather than remote systems may therefore be more robust and cheaper, allowing more frequent saving. For instance, in a small app I made, I save to localstorage on every keystroke. Worked flawlessly. Many PWA frameworks support this out of the box: for instance, redux-persist for react, or ngrx-store-persist for ngrx.
That is, you don't need to detect idle states to prevent information loss when the user exits without saving.
On the other hand, if you want to track user activity for statistics purposes, calculating an idle state makes sense. It's been a while since the last time I did this, but I did something simple like:
<body onclick="userIsHere()" onkeypress="userIsHere()">
<script>
let lastUserInteraction = new Date();
function userIsHere() {
lastUserInteraction = new Date();
}
function isIdle() {
const millis = new Date().getTime() - lastUserInteraction.getTime();
return millis > 5 * 60 * 1000;
}
setInterval(() => {
console.log(isIdle())
}, 1000);
</script>
</body>
Since DOM events naturally bubble to the top, these handlers should observe all user interactions. Theoretically, it is possible for a UI element to prevent this with stopPropagation() but I found that the UI elements I used didn't do that.
1 comment thread