views:

299

answers:

6

I'm making a webpage with dynamic content that enters the view with AJAX polling. The page JS occasionally downloads updated information and renders it on the page while the user is reading other information. This sort of thing is costly to bandwidth and processing time. I would like to have the polling pause when the page is not being viewed.

I've noticed most of the webpages I have open spend the majority of their time minimized or in a nonviewed tab. I'd like to be able to pause the scripts until the page is actually being viewed.

I have no idea how to do it, and it seems to be trying to break out of the sandbox of the html DOM and reach into the user's system. It may be impossible, if the JS engine has no knowledge of its rendering environment. I've never even seen a different site do this (not that the user is intended to see it...)

So it makes for an interesting question for discussion, I think. How would you write a web app that is CPU heavy to pause when not being used? Giving the user a pause button is not reliable, I'd like it to be automatic.

+2  A: 

I've looked at that problem before for a research project. At the time (2-3 years ago) I did not find a way to get information from the browser about whether or not you are minimized :(

Uri
+3  A: 

How about setting an "inactivity timeout" which gets reset every time a mouse or keyboard event is received in the DOM? I believe this is how most IM programs decide that you're "away" (though they do it by hooking the input messages at the system-wide level)

jlew
A: 

You can listen for mousemove and keypress events. If one of those has been fired in the past X seconds, then continue with your updating. Otherwise, don't update.

It's not perfect, but I think it's the best you can do with pure JS.

If you want to venture into the world of Flash, Silverlight, or Java, you may be able to get more information from the browser.

EndangeredMassa
+4  A: 

Your best solution would be something like this:

 var inactiveTimer;
 var active = true;
 function setTimer(){
  inactiveTimer = setTimeOut("stopAjaxUpdateFunction()", 120000); //120 seconds
 }
 setTimer();
 document.onmouseover = function() { clearTimeout ( inactiveTimer ); 
                                     setTimer(); 
                                     resumeAjaxUpdate();
  }; //clear the timer and reset it.
 function stopAjaxUpdateFunction(){
  //Turn off AJAX update
  active = false;   
 }
 function resumeAjaxUpdate(){
  if(active == false){
   //Turn on AJAX update
   active = true;
  }else{
   //do nothing since we are still active and the AJAX update is still on.
  }    
 }

The stopAjaxUpdateFunction should stop the AJAX update progress.

Pim Jager
You would want a mechanism to restart the updates when activity resumed.
Benry
Just add that to the onmouseover function (see updated answer)
Pim Jager
Won't dragging the mouse across the screen once cause about a thousand cleartimeout() setTimer() calls? Is that okay to do?
Karl
not quite sure, But I don't think so. Try setting up a simple test: document.mouseover = function() { document.write('hai'); };see how that does
Pim Jager
It will fire for every mouseover event that bubbles to it, so any time you mouse over an element it will fire this event. Even though it works, I wouldn't have recommended this method and not just for the reasons stated. I read pages using my keyboard, not my mouse - I scroll up and down with `(page) up/down`, I move back/forward with `Alt+Left/Alt+Right`, your page with this code would most likely stop updating for me.
Andy E
+2  A: 

First check when the window loses and gains focus.

window.onblur = function () { /* stop */ };
window.onfocus =  function () { /* start */ };

Also, for various reasons, the user may stop reading the page without causing it to lose focus (e.g. he gets up and walks away from the computer). In that case, you have to assume after a period of inactivity (no mouse or keyboard events) that the users' attention has left the page. The code to do that is described in another answer.

Patrick McElhaney
that has the problem of not being able to detect a user that has just walked away from screen with the page open.
Pim Jager
Who says you can't have a blur check and an inactivity check? (I've updated my answer.)
Patrick McElhaney
Yeah ok, didn't look at it that way. blur and focus defenitly are nice because they are instant.
Pim Jager
Only downside is that `window.onblur` and `window.onfocus` don't work correctly in IE.
Andy E
+1  A: 

I know you've already accepted an answer but I'd personally use a combination of several of the answers mentioned here for various reasons, including:

  • Using mouse events only alienates users proficient at keyboard based browsing.
  • Using blur/focus events don't allow for users who go make a cup of tea ;-)

I'd most likely use something like the following as a guideline:

var idleTimer, userIsIdle, pollingTimer;
function resetTimer()
{
    if (userIsIdle)
        setBack();
    window.clearTimeout(idleTimer);
    idleTimer = window.setTimeout(setIdle, 120000); // 2 minutes of no activity    
}
function window.onload ()
{
    pollingTimer = window.setTimeout(runPollingFunction, 30000);
    resetTimer();
    if (window.navigator.appName == "Microsoft Internet Explorer")
        document.onfocusin  = resetTimer,
        document.onfocusout = setIdle;
    else
        window.onfocus = resetTimer,
        window.onblur = setIdle;
}
document.onkeydown = document.onmousemove = resetTimer;
function setIdle()
{
    userIsIdle = true;
    window.clearTimeout(pollingTimer); // Clear the timer that initiates polling
    window.clearTimeout(setIdle);
}
function setBack()
{
    userIsIdle = false;
    runPollingFunction(); // call the polling function to instantly update page
    pollingTimer = window.setTimeout(runPollingFunction, 300000);
}

E&OE - It's 00:49am here and this IE tab just crashed on me twice (i know! rollseyes) so it's quite possible some of that needs jiggling around.

Andy E
Just looked at the date in the question - I SWEAR this was in the active questions list!
Andy E
I linked to it from a similar thread yesterday and it got some hits and maybe an upvote, which did put it back into the active questions list. Stack-O has voodoo that way. Thanks for the response anyway, it's helpful.
Karl
Thanks for the +1, I appreciate it :)
Andy E