1. Background
Recently, I often encounter "When the user has no operation within a certain period of time, he will jump to a certain page.” demand.
After surfing the Internet, I did not find a better JS package to solve this problem, so I decided to implement it myself.
2. How to determine whether the page is idle (the user has no operation for a long time)
First of all, we need to know what is idleness? If the user does not perform any operations on the web page for a certain period of time, the current web page is idle.
Users operate web pages simply bymouse
、keyboard
Two input devices (no consideration of handles and other devices). Therefore, we can listen to the corresponding input events to determine whether the web page is idle (whether the user operates the web page).
- Listen to mouse movement events
mousemove
; - Listen to the keyboard press event
mousedown
; - After the user enters the web page, set a delay jump. If the above event is triggered, remove the delay and start over.
3. Implementation of web page idle detection
3.1 Simple implementation
The following code simply implements a method to judge the idle web page.
const onIdleDetection = (callback, timeout = 15, immediate = false) => { let pageTimer; const onClearTimer = () => { pageTimer && clearTimeout(pageTimer); pageTimer = undefined; }; const onStartTimer = () => { onClearTimer(); pageTimer = setTimeout(() => { callback(); }, timeout * 1000); }; const startDetection = () => { onStartTimer(); ('mousedown', onStartTimer); ('mousemove', onStartTimer); }; const stopDetection = () => { onClearTimer(); ('mousedown', onStartTimer); ('mousemove', onStartTimer); }; const restartDetection = () => { onClearTimer(); onStartTimer(); }; if (immediate) { startDetection(); } return { startDetection, stopDetection, restartDetection }; };
Maybe you noticed that I didn't targetonStartTimer
If you perform anti-shake, will this affect the performance?
Yes, it must have such a little impact, so why don’t I add anti-shake?
This is because after adding anti-shake,setTimeout
Nesting, nestingsetTimeout
There will be accuracy issues (refer to)。
Maybe you will also say that inactive tabs (web pages are hidden)setTimeout
There will be problems with the execution and accuracy (Timeout for reference inactive tags)。
The above problems do exist, so let’s solve them one by one!
3.2 Handle frequent triggering problems
We can solve this problem by adding a variable to record the execution time and exit the function directly when the next execution and the current time interval is less than a certain value (application of throttling ideas).
const onIdleDetection = (callback, timeout = 15, immediate = false) => { let pageTimer; // Record the start time let beginTime = 0; const onStartTimer = () => { // When the trigger interval is less than 100ms, return directly const currentTime = (); if (pageTimer && currentTime - beginTime < 100) { return; } onClearTimer(); // Update start time beginTime = currentTime; pageTimer = setTimeout(() => { callback(); }, timeout * 1000); }; const onClearTimer = () => { pageTimer && clearTimeout(pageTimer); pageTimer = undefined; }; const startDetection = () => { onStartTimer(); ('mousedown', onStartTimer); ('mousemove', onStartTimer); }; const stopDetection = () => { onClearTimer(); ('mousedown', onStartTimer); ('mousemove', onStartTimer); }; const restartDetection = () => { onClearTimer(); onStartTimer(); }; if (immediate) { startDetection(); } return { startDetection, stopDetection, restartDetection }; };
3.3 Handle the situation where the page is hidden (full implementation)
We can monitorvisibilitychange
Events, removing the delay when the page is hidden, and then continuing to time when the page is displayed, thus solving this problem.
/** * Web page idle detection * @param {() => void} callback executes when it is idle, that is, it triggers when there is no operation for a certain period of time * @param {number} [timeout=15] Duration, default 15s, unit: seconds * @param {boolean} [immediate=false] Whether to start immediately, default false * @returns */ const onIdleDetection = (callback, timeout = 15, immediate = false) => { let pageTimer; let beginTime = 0; const onClearTimer = () => { pageTimer && clearTimeout(pageTimer); pageTimer = undefined; }; const onStartTimer = () => { const currentTime = (); if (pageTimer && currentTime - beginTime < 100) { return; } onClearTimer(); beginTime = currentTime; pageTimer = setTimeout(() => { callback(); }, timeout * 1000); }; const onPageVisibility = () => { // When the page display status changes, remove the delay onClearTimer(); if ( === 'visible') { const currentTime = (); // When the page is displayed, calculate the time. If the limit time is exceeded, the callback function will be directly executed. if (currentTime - beginTime >= timeout * 1000) { callback(); return; } // Continue to time pageTimer = setTimeout(() => { callback(); }, timeout * 1000 - (currentTime - beginTime)); } }; const startDetection = () => { onStartTimer(); ('mousedown', onStartTimer); ('mousemove', onStartTimer); ('visibilitychange', onPageVisibility); }; const stopDetection = () => { onClearTimer(); ('mousedown', onStartTimer); ('mousemove', onStartTimer); ('visibilitychange', onPageVisibility); }; const restartDetection = () => { onClearTimer(); onStartTimer(); }; if (immediate) { startDetection(); } return { startDetection, stopDetection, restartDetection }; };
Through the above code, we have fully implemented a method of web page idle state detection.
4. Extended
The Chrome browser actually provides aIdle Detection
API is used to detect the idle state of web pages, but this API is still an experimental feature and is not supported by Firefox and Safari.API Reference
This is the article about using JavaScript to detect whether a web page is idle. For more related JavaScript detection web page content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!