是否有可能在JavaScript中检测“空闲”时间?

我的主要用例可能是预取或预加载内容。

我将空闲时间定义为用户不活动或没有任何CPU使用的时间段


当前回答

所有这些解决方案的问题,尽管是正确的,但在使用PHP、. net或在应用程序中考虑会话超时值集时,它们是不切实际的。为ColdFusion开发人员提供cfc文件。

上述解决方案设置的时间需要与服务器端会话超时同步。如果两者不同步,您可能会遇到一些问题,这些问题只会让用户感到沮丧和困惑。

例如,服务器端会话超时可能被设置为60分钟,但用户可能认为他/她是安全的,因为JavaScript空闲时间捕获增加了用户在单个页面上花费的总时间。用户可能花了很多时间填写一个很长的表单,然后去提交。会话超时可能在处理表单提交之前开始。

我倾向于只给用户180分钟,然后使用JavaScript自动注销用户。实际上,使用上面的一些代码来创建一个简单的计时器,但是没有捕获鼠标事件部分。

通过这种方式,我的客户端和服务器端时间完全同步。如果您在UI中向用户显示时间,就不会出现混乱。每次在CMS中访问一个新页面时,服务器端会话和JavaScript计时器都会被重置。简单而优雅。如果一个用户在一个页面上停留超过180分钟,首先我认为这个页面有问题。

其他回答

下面是tvanfosson的想法的粗略jQuery实现:

$(document).ready(function(){

   idleTime = 0;

   //Increment the idle time counter every second.
   var idleInterval = setInterval(timerIncrement, 1000);
   
   function timerIncrement()
   {
     idleTime++;
     if (idleTime > 2)
     {
       doPreload();
     }
   }
   
   //Zero the idle timer on mouse movement.
   $(this).mousemove(function(e){
      idleTime = 0;
   });
   
   function doPreload()
   {
     //Preload images, etc.
   }
   
})

我已经测试了这段代码工作文件:

var timeout = null;
    var timee = '4000'; // default time for session time out.
    $(document).bind('click keyup mousemove', function(event) {

    if (timeout !== null) {
            clearTimeout(timeout);
        }
        timeout = setTimeout(function() {
              timeout = null;
            console.log('Document Idle since '+timee+' ms');
            alert("idle window");
        }, timee);
    });

下面是一个在Angular中完成的AngularJS服务。

/* Tracks now long a user has been idle.  secondsIdle can be polled 
   at any time to know how long user has been idle. */
fuelServices.factory('idleChecker',['$interval', function($interval){
    var self = {
        secondsIdle: 0,
        init: function(){
            $(document).mousemove(function (e) {
                self.secondsIdle = 0;
            });
            $(document).keypress(function (e) {
                self.secondsIdle = 0;
            });
            $interval(function(){
                self.secondsIdle += 1;
            }, 1000)
        }
    }
    return self;
}]);

请记住,这个空闲检查器将为所有路由运行,因此应该在angular应用程序加载时在.run()中初始化它。然后你可以使用idleChecker。在每个路由内的secondside。

myApp.run(['idleChecker',function(idleChecker){
    idleChecker.init();
}]);

改进Equiman(原始)的答案:

function idleLogout() {
    var t;
    window.onload = resetTimer;
    window.onmousemove = resetTimer;
    window.onmousedown = resetTimer;  // catches touchscreen presses as well      
    window.ontouchstart = resetTimer; // catches touchscreen swipes as well      
    window.ontouchmove = resetTimer;  // required by some devices 
    window.onclick = resetTimer;      // catches touchpad clicks as well
    window.onkeydown = resetTimer;   
    window.addEventListener('scroll', resetTimer, true); // improved; see comments

    function yourFunction() {
        // your function for too long inactivity goes here
        // e.g. window.location.href = 'logout.php';
    }

    function resetTimer() {
        clearTimeout(t);
        t = setTimeout(yourFunction, 10000);  // time is in milliseconds
    }
}
idleLogout();

除了活动检测方面的改进,以及从文档到窗口的更改之外,这个脚本实际上调用了函数,而不是让它闲置着。

它不会直接捕获零CPU使用情况,但这是不可能的,因为执行函数会导致CPU使用。用户不活动最终导致CPU使用率为零,因此它间接地捕捉到CPU使用率为零。

就像它可以得到的那样简单,检测鼠标移动的时间:

var idle = false;

document.querySelector('body').addEventListener('mousemove', function(e) {
    if(idle!=false)
        idle = false;
});

var idleI = setInterval(function()
{
    if(idle == 'inactive')
    {
        return;
    }

    if(idle == true)
    {
        idleFunction();
        idle = 'inactive';
        return;
    }

    idle = true;
}, 30000); // half the expected time. Idle will trigger after 60 s in this case.

function idleFuntion()
{
   console.log('user is idle');
}