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

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

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


当前回答

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

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

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

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

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

其他回答

下面是一个在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回答的良好核心逻辑。)

sessionExpiration.js


sessionExpiration.js是轻量级的,但有效和可定制的。一旦实现,只在一行中使用:

sessionExpiration(idleMinutes, warningMinutes, logoutUrl);

Affects all tabs of the browser, not just one. Written in pure JavaScript, with no dependencies. Fully client side. (If so wanted.) Has warning banner and countdown clock, that is cancelled by user interaction. Simply include the sessionExpiration.js, and call the function, with arguments [1] number of idle minutes (across all tabs) until user is logged out, [2] number of idle minutes until warning and countdown is displayed, and [3] logout url. Put the CSS in your stylesheet. Customize it if you like. (Or skip and delete banner if you don't want it.) If you do want the warning banner however, then you must put an empty div with ID sessExpirDiv on your page (a suggestion is putting it in the footer). Now the user will be logged out automatically if all tabs have been inactive for the given duration. Optional: You may provide a fourth argument (URL serverRefresh) to the function, so that a server side session timer is also refreshed when you interact with the page.


这是一个例子,如果你不改变CSS,它看起来是什么样子的。

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

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

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

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

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

我创建了一个小的库来做这个:

https://github.com/shawnmclean/Idle.js

描述:

微小的JavaScript库报告用户在浏览器中的活动 (离开,空闲,没有看网页,在不同的标签,等)。这是独立的 其他JavaScript库,如jQuery。

Visual Studio用户可以从NuGet通过:

Install-Package Idle.js

我使用这种方法,因为您不需要在事件触发时不断重置时间。相反,我们只记录时间,这将生成空闲的起始点。

function idle(WAIT_FOR_MINS, cb_isIdle) {
    var self = this,
        idle,
        ms = (WAIT_FOR_MINS || 1) * 60000,
        lastDigest = new Date(),
        watch;
    //document.onmousemove = digest;
    document.onkeypress = digest;
    document.onclick = digest;

    function digest() {
       lastDigest = new Date();
    }

    // 1000 milisec = 1 sec
    watch = setInterval(function() {
        if (new Date() - lastDigest > ms && cb_isIdel) {
            clearInterval(watch);
            cb_isIdle();
        }

    }, 1000*60);
},