# Detecting If the User is Idle or Inactive by [ kirupa](https://www.kirupa.com/me/index.htm) | filed under [JavaScript 101](https://www.kirupa.com/javascript/learn_javascript.htm) Some apps require your constant attention. Such apps often include games, media players, anything that is CPU/battery intensive, and so on. For these kinds of apps, it may be important (as well as user-friendly) to do something when a user is no longer actively interacting with your app. Take a look at the following example: Your browser does not support inline frames or is currently configured not to display inline frames. More than likely, you are seeing a moon on a dark gray background. If you hover over the example or click/tap anywhere, notice that your app suddenly jumps to life and shows an animated rocket. As long as you keep interacting with the example by moving the mouse or clicking around, the rocket will continue to display. If you don't do anything for 2 seconds, the example thinks you are no longer paying attention and goes back to the dark background with the moon. In this article, you will learn how to detect when a user has gone inactive (aka idle) using nothing but a few lines of sweet SWEET JavaScript. Onwards! ## Detecting Inactivity The way we are going to detect inactivity is pretty straightforward. We have a timer that starts ticking once a user stops interacting with the app. Let's define "stops interacting" as when a user hasn't fiddled with the mouse, keyboard, or the screen (by touching / tapping) for a period of time. The basic code for this looks as follows: ``` var timeoutID; function setup() { this.addEventListener("mousemove", resetTimer, false); this.addEventListener("mousedown", resetTimer, false); this.addEventListener("keypress", resetTimer, false); this.addEventListener("DOMMouseScroll", resetTimer, false); this.addEventListener("mousewheel", resetTimer, false); this.addEventListener("touchmove", resetTimer, false); this.addEventListener("MSPointerMove", resetTimer, false); startTimer(); } setup(); function startTimer() { // wait 2 seconds before calling goInactive timeoutID = window.setTimeout(goInactive, 2000); } function resetTimer(e) { window.clearTimeout(timeoutID); goActive(); } function goInactive() { // do something } function goActive() { // do something startTimer(); } ``` If you want to incorporate this code as-is, you should make a few minor tweaks. First, our code currently considers a user to be inactive after 2 seconds of idling. You can change how long to wait before playing the "inactive card" in the following line: ``` function startTimer() { // wait 2 seconds before calling goInactive timeoutID = window.setTimeout(goInactive, 2000); } ``` Just replace the last argument to the ` setTimeOut` function with the number of milliseconds you want to wait. Next, you should specify what you want your app to do when the user is inactive and when they are active. You can specify your wants in the appropriately named `goInactive` and `goActive` functions: ``` function goInactive() { // do something } function goActive() { // do something startTimer(); } ``` That's all there is to using this very simple script for detecting when users become inactive. To see this code at work, you can view the source for the example you saw earlier by using your browser's **View Source** command [on this page](examples/detecting_inactivity.htm). In the next section, let's deconstruct this code and understand how it works. ## The Code Explained Our code can be divided into two parts. The first part deals with setting up all of the events to ensure we are detecting inactivity properly. The second part is setting and resetting the timer depending on whether your user is interacting with the app or not. ### Listening for Events The easy part is setting up the events: ``` function setup() { this.addEventListener("mousemove", resetTimer, false); this.addEventListener("mousedown", resetTimer, false); this.addEventListener("keypress", resetTimer, false); this.addEventListener("DOMMouseScroll", resetTimer, false); this.addEventListener("mousewheel", resetTimer, false); this.addEventListener("touchmove", resetTimer, false); this.addEventListener("MSPointerMove", resetTimer, false); startTimer(); } setup(); ``` Our code listens for various mouse, keyboard, and touch events to ensure that we don't accidentally declare a user as being inactive when he/she is actually still interacting with the app. If any of these events are overheard, the `resetTimer` function acts as the event handler and gets called. ### Meet the Timer The timer is what determines when to declare an active app as being inactive. That important task is handled by the `startTimer` and `resetTimer` functions: ``` function startTimer() { // wait 2 seconds before calling goInactive timeoutID = window.setTimeout(goInactive, 2000); } function resetTimer(e) { window.clearTimeout(timeoutID); goActive(); } ``` The `startTimer` function gets called at the very beginning by our `setup` function, and it initializes our global `timeoutID` variable to an ID value returned by calling the ` setTimeout` function: ``` function startTimer() { // wait 2 seconds before calling goInactive timeoutID = window.setTimeout(goInactive, 2000); } ``` In our example, the `setTimeout` function calls `goInactive` after two seconds. The only way to prevent our app from going into an inactive state is to ensure we reset this `setTimeout` call so that it never gets a chance to call the ` goInactive` function. This resetting is handled in the `resetTimer` function - a function that gets called when any of the events we are listening for gets fired: ``` function resetTimer(e) { window.clearTimeout(timeoutID); goActive(); } ``` More specifically, we negate the `setTimeout` call from earlier by using the `clearTimeout` function. The `timeoutID` variable that you initialized as part of the `setTimeout` call is what you pass in to the `clearTimeout` function to ensure you are stopping the right timer. Once the timer is stopped, we call the ` goActive` function which creates the timer all over again by calling `startTimer`: ``` function goActive() { // do something startTimer(); } ``` The `startTimer` and `resetTimer` functions get called constantly when users are interacting with your app. With every interaction, your timer gets reset. With every pause in the interaction, your timer starts counting down again until it gets a chance to call the `goInactive` function. Pretty awesome, right? ## Conclusion Most of the time, you probably don't care whether a user is actively interacting with your app or not. Your app will simply be indifferent. During those other times, what you decide to do will vary depending on what exactly your app does. A game may choose to pause if nothing is going on. A media player might choose to hide all of the playback controls when the user stops interacting with it. A document editor might auto-save when it detects a pause.