Created
May 16, 2021 03:18
-
-
Save meglio/7791acbcd6ff515b65ea87b16517b076 to your computer and use it in GitHub Desktop.
Fires an 'idleTimeSeconds' event when the page is idle for the certain amount of seconds
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import $ from 'jquery'; | |
export const IDLE_EVENT_NAME = 'idleTimeSeconds'; | |
/** | |
* How often an 'idleTimeSeconds' event is fired on the document instance. | |
* | |
* @type {number} | |
*/ | |
const IDLE_EVENT_RATE_SECONDS = 10; | |
/** | |
* How often the idle time is checked against the IDLE_EVENT_RATE_SECONDS. | |
* | |
* Should be much smaller than the value of IDLE_EVENT_RATE_SECONDS | |
* (the smaller the value is, the more precisely the event is fired) - | |
* because the actual delay may be longer, see "Reasons for delays | |
* longer than specified in WindowOrWorkerGlobalScope.setTimeout() for examples": | |
* https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout#Reasons_for_delays_longer_than_specified | |
* | |
* @type {number} | |
*/ | |
const IDLE_TIMER_RATE_SECONDS = 1; | |
/** | |
* Because the actual timer delay may be longer, we track the timestamp | |
* when the idle time started, instead of incrementally adding to the total idle time. | |
* Having a starting point, we can always calculate the idle time precisely | |
* without accumulating delay errors. | |
* | |
* @type {number} | |
*/ | |
let idleStartTimeMilliseconds; | |
/** | |
* Holds the interval reference. | |
*/ | |
let idleInterval; | |
/** | |
* Holds the value of the latest idle time value | |
* for which the event was fired (integer value in seconds). | |
* | |
* The value is therefore factor of IDLE_EVENT_RATE_SECONDS. | |
* | |
* @type {number} | |
*/ | |
let lastFiredSeconds; | |
const $document = $(document); | |
/** | |
* Resets the idle timer. | |
* Called on user interaction events, like keydown or touchstart. | |
*/ | |
function resetIdleStartTime() { | |
// Reset the timestamp when the idle time started | |
idleStartTimeMilliseconds = (new Date).getTime(); | |
// Reset the latest idle time value for which the even was fired | |
// (integer value in seconds). | |
lastFiredSeconds = 0; | |
} | |
/** | |
* Ticks every IDLE_TIMER_RATE_SECONDS, which is more often than the expected | |
* idle event firing rate. | |
* | |
* Fires the 'idleTimeSeconds' event on the document instance. | |
*/ | |
function timerCallback() { | |
const nowMilliseconds = (new Date).getTime(); | |
const idleTimeSeconds = Math.floor((nowMilliseconds - idleStartTimeMilliseconds) / 1000); | |
// When do we expect the idle event to be fired again? | |
// For example, if the event firing rate is 10 seconds, | |
// and last time it was fired at 40 seconds of idle time, | |
// the next one will be at 40 + 10 = 50 seconds. | |
const nextIdleSecondsToFire = lastFiredSeconds + IDLE_EVENT_RATE_SECONDS; | |
if (idleTimeSeconds >= nextIdleSecondsToFire) { | |
// Record last fired idle time that is factor of the rate, | |
// so that we keep firing the event as close to the desired rate as possible | |
lastFiredSeconds = nextIdleSecondsToFire; | |
$document.triggerHandler(IDLE_EVENT_NAME, [idleTimeSeconds]); | |
} | |
} | |
// Initialize the idle timer once only per the document instance | |
$(function() { | |
// Start the idle timer | |
idleInterval = setInterval(timerCallback, IDLE_TIMER_RATE_SECONDS * 1000); | |
// Reset the idle time start timestamp | |
$document.on('mousemove keydown mousedown touchstart', resetIdleStartTime); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment