SoFunction
Updated on 2025-03-09

Use JavaScript to detect whether the web page is idle

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 bymousekeyboardTwo 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 eventsmousemove
  • Listen to the keyboard press eventmousedown
  • 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 targetonStartTimerIf 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,setTimeoutNesting, nestingsetTimeoutThere will be accuracy issues (refer to)。

Maybe you will also say that inactive tabs (web pages are hidden)setTimeoutThere 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 monitorvisibilitychangeEvents, 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 DetectionAPI 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!