Detecting If the User is Idle or Inactive

by kirupa | 11 September 2013

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.


This is a companion discussion topic for the original entry at http://www.kirupa.com/html5/detecting_if_the_user_is_idle_or_inactive.htm

Hi,

It’s a very good Script.

I’m using this script in my website for checking user activity.

Thx.

Hi this is a great script thanks heaps!
I want to use on a page that contains an iframe, but I noticed that if the user clicks or hover within the iframe, it doesn’t register the movements and therefore go inactive no matter what,
Any workaround to have this script register mouse moves, clicks or touchevents ( ipads) on iframes?

Jane - does this help? https://stackoverflow.com/questions/5645485/detect-mousemove-when-over-an-iframe

I am not in front of a computer to verify, but it seems like it would work :slight_smile:

thanks, it would… but my iframe is from a different domain so I am running into a cross domain security[ issue. I have managed to adapt your script and have it half work. The timer starts ticking once an activity is detected on the iframe, but the timer doesn’t reset if the user becomes inactive. So once an activity is detected the page will refresh after 7 mins
here it is if you want to have a look at it or if it can be useful for anyone

<script>
    var timeoutID;
    var myConfObj = {
  iframeMouseOver : false
};

function startTimer() {
    // wait 2 seconds before calling goInactive
    timeoutID = window.setTimeout(goInactive, 70000);
}
function goInactive() {
    location.reload();
       //window.location.replace("https://www.musclemedicine.com.au/make-a-booking");
}
function goActive() {
    // do something 
    startTimer();
}
function resetTimer(e) {
   window.clearTimeout(timeoutID);
   goActive();
}

window.addEventListener('blur',function(){
  if(myConfObj.iframeMouseOver){
  resetTimer();
  }
  else {
    goInactive();
   
  }
});

document.getElementById('nookalbooking').addEventListener('mouseover',function(){
   myConfObj.iframeMouseOver = true;

});

document.getElementById('nookalbooking').addEventListener('touchmove',function(){
   myConfObj.iframeMouseOver = true; 
});

document.getElementById('nookalbooking').addEventListener('MSPointerMove',function(){
   myConfObj.iframeMouseOver = true; 
});


document.getElementById('nookalbooking').addEventListener('mouseout',function(){
    myConfObj.iframeMouseOver = false;
    
    
     
});

</script>

Sorry for the delay in getting back to you. I’ll look into this tomorrow-ish. I’m personally interested in figuring this out as well, for it’s an interesting problem :slight_smile:

I don’t think there’s a way to have both of best world’s - interaction within a x-domain iframe and detection of that interaction in your frame without the other frame’s cooperation. If you want to capture events on your end, you can use an overlay for that, but then you lose interaction within the frame itself. And when interacting with the x-frame you’re locked out of knowing what that interaction is.

1 Like

That makes sense. With WebView-like elements in app frameworks/languages/etc. (Electron, Android, iOS, Windows, etc.) there are ways to inject scripts that you can then call from your outer app frame. I was hoping that something similar can be done using iframes! :stuck_out_tongue:

You can - using a browser extension. But this would require users of your site to install that extension (not unlike the requirement to install your app)

1 Like

Ok, but, if a user is seeing a embbeded video, like youtube or facebook?

You can always disable the “idle detection” functionality when a video is playing :slight_smile:

Hi,

Code is working perfectly. I just had one question that How to stop the timer to check the Idle time? For example if I am checking certain amount of Idle time and after that I am making user Logged Out from the application. So When User logged out that time I want to stop the timer.

In this case time will continue as it is, So my question is how to stop the timer after certain event?

Regards,
Mihit

In the function you have for logging out, just call clearTimeout(timerID) to stop the timer :slight_smile:

@kirupa It only cleanTimeout of particular timeId but the problem is in the background setup function is running so whenever you do any event than again resetTimer function called from setup and timer will Start Again.

What I need is after logout of user this code completely stops working(All timer and setup function which called earlier has to stop as well.)

Any Idea!!

I am on my phone, so I can’t give you a working solution. One approach might be to have a global toggle variable that all of the timer-related functions listen to. If the toggle variable is set to true, then the code behaves as currently designed. If the toggle value is set to false, then the start timer, reset timer, and related functions never run. Only the code for clearing the timer will run.

Does this help?

Hi Kirupa,

Thanks for the swift response. I analyze your scenario and come the below conclusion.

That solution will work for scenario like: either I want to start function or don’t want to start function(based on that flag which you mentioned), What I am looking is after starting the function How can I stop(Currently this function always executed in loop). How can i destroy it?

In the scenario which you mentioned, after setting the flag true, timer will start but when user logout even if i set flag to false, all the function will run as it is. So In short I am looking for how to destroy this complete loop.

Thanks.

The resetTimer you are calling clears the timer and starts it all over again. All you are looking for is a way to clear the timer without the “starting all over” part.

That would mean you have a new function that only calls this: window.clearTimeout(timeoutID);

I am a bit confused then if that isn’t what you are trying to do :slight_smile: