如果用户当前在页面上处于活动状态,我如何使用JavaScript / jQuery进行检测?

时间:2009-06-17 20:07:00

标签: javascript jquery

我需要在当前页面上检测用户何时处于非活动状态(不是单击或键入)超过30分钟。

我认为最好使用贴在身体标签上的事件blubbling,然后继续重置计时器30分钟,但我不确定如何创建它。

我有jQuery可用,虽然我不确定其中有多少实际使用jQuery。

编辑:我更需要知道他们是否正在积极使用该网站,因此点击(更改字段或字段中的位置或选择复选框/无线电)或输入(在输入中, textarea等)。如果他们在另一个标签页或使用其他程序,那么我的假设是他们没有使用该网站,因此应该注销(出于安全原因)。

编辑#2:所以每个人都很清楚,这根本不是确定用户是否已登录,经过身份验证或其他任何内容。现在,如果用户在30分钟内没有发出页面请求,服务器会将用户注销。此功能可防止有人花费> 30分钟填写表单然后提交表单以发现他们尚未注销的时间。因此,这将与服务器站点结合使用,以确定用户是否处于非活动状态(不是单击或键入)。基本上,交易是在闲置25分钟后,他们将看到一个对话框输入他们的密码。如果他们不在5分钟内,系统会自动将其注销,并且服务器的会话将被注销(下次访问页面时,与大多数站点一样)。

Javascript仅用作对用户的警告。如果JavaScript被禁用,那么他们将不会收到警告(并且大部分网站都无法正常工作),他们将在下次请求新页面时注销。

10 个答案:

答案 0 :(得分:24)

这就是我想出来的。它似乎适用于大多数浏览器,但我想确保它始终可以在任何地方使用:

var timeoutTime = 1800000;
var timeoutTimer = setTimeout(ShowTimeOutWarning, timeoutTime);
$(document).ready(function() {
    $('body').bind('mousedown keydown', function(event) {
        clearTimeout(timeoutTimer);
        timeoutTimer = setTimeout(ShowTimeOutWarning, timeoutTime);
    });
});

有人看到任何问题吗?

答案 1 :(得分:15)

您可以观看mouse movement,但这是关于用户在没有收听点击事件的情况下仍然存在的最佳信息。但是javascript无法判断它是活动标签还是浏览器甚至是打开的。 (好吧,你可以得到浏览器的宽度和高度,并告诉你它是否被最小化)

答案 2 :(得分:15)

我刚刚做了类似的事情,虽然使用Prototype而不是JQuery,但我想只要JQuery支持自定义事件,实现就会大致相同。

简而言之,IdleMonitor是一个观察鼠标和键盘事件的类(根据您的需要进行相应调整)。每30秒重置计时器并广播一个状态:idle事件,除非它获得一个鼠标/键事件,在这种情况下它会广播一个状态:active event。

var IdleMonitor = Class.create({

    debug: false,
    idleInterval: 30000, // idle interval, in milliseconds
    active: null,
    initialize: function() {
        document.observe("mousemove", this.sendActiveSignal.bind(this));
        document.observe("keypress", this.sendActiveSignal.bind(this));
        this.timer = setTimeout(this.sendIdleSignal.bind(this), this.idleInterval);
    },

    // use this to override the default idleInterval
    useInterval: function(ii) {
        this.idleInterval = ii;
        clearTimeout(this.timer);
        this.timer = setTimeout(this.sendIdleSignal.bind(this), ii);
    },

    sendIdleSignal: function(args) {
        // console.log("state:idle");
        document.fire('state:idle');
        this.active = false;
        clearTimeout(this.timer);
    },

    sendActiveSignal: function() {
        if(!this.active){
            // console.log("state:active");
            document.fire('state:active');
            this.active = true;
            this.timer = setTimeout(this.sendIdleSignal.bind(this), this.idleInterval);
        }
    }
});

然后我刚刚创建了另一个在其中包含以下内容的类:

Event.observe(document, 'state:idle', your-on-idle-functionality);
Event.observe(document, 'state:active', your-on-active-functionality)

答案 3 :(得分:15)

Ifvisible.js是一个交叉浏览器轻量级解决方案。它可以检测用户何时切换到另一个选项卡并返回当前选项卡。它还可以检测用户何时进入空闲状态并再次变为活动状态。它非常灵活。

答案 4 :(得分:3)

使用jQuery,您可以轻松地观察鼠标移动,并使用它来设置指示活动为true的变量,然后使用vanilla javascript,您可以每30分钟(或任何其他间隔)检查此变量以查看其是否为真。如果它是假的,运行你的功能或其他什么。 查找setTimeout和setInterval以进行计时。您也可能每分钟左右运行一次函数将变量重置为false。

答案 5 :(得分:3)

Ifvisible是一个很好的JS库,用于检查用户是否不活动。

Exception in thread "main" java.lang.NullPointerException

    at ArrayCalc.arrayCalc(ArrayCalc.java:13)
    at ArrayCalc.main(ArrayCalc.java:33)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

Process finished with exit code 1

答案 6 :(得分:2)

这是我的镜头:

var lastActivityDateTime = null;

function checkActivity( )
{
    var currentTime = new Date();
    var diff = (lastActivityDateTime.getTime( ) - currentTime.getTime( ));
    if ( diff >= 30*60*1000)
    {
        //user wasn't active;
        ...
    }
    setTimeout( 30*60*1000-diff, checkActivity);
}

setTimeout( 30*60*1000, checkActivity); // for first time we setup for 30 min.


// for each event define handler and inside update global timer
$( "body").live( "event_you_want_to_track", handler);

function handler()
{
   lastActivityDateTime = new Date();
   // rest of your code if needed.
}

答案 7 :(得分:2)

如果这是一个安全问题,使用javascript执行此客户端绝对是执行此检查的管道的错误结束。用户可以轻松禁用javascript:您的应用程序会做什么?如果用户在超时之前关闭浏览器该怎么办他们会退出吗?

大多数服务器端框架都有登录的某种会话超时设置。只需使用它并节省自己的工程工作。

你不能依赖于人们无法在没有javascript的情况下登录的假设,因此用户拥有javascript。这样的假设对于任何坚定的,甚至是受过适度教育的攻击者都没有威慑力。

使用javascript就像一名保安人员将钥匙交给银行保险库。它的唯一运作方式就是信仰。

当我说以这种方式使用javascript(并且需要使用javascript登录!!)时,请相信我,这是一种非常厚重的设计任何类型的网络应用程序的方式。

答案 8 :(得分:1)

不使用JS,更简单(更安全)的方法就是将lastActivity时间戳存储在用户的会话中并在页面加载时进行检查。假设您使用的是PHP(您可以轻松地将此代码重做为另一个平台):

if(($_SESSION['lastAct'] + 1800) < time()) {
    unset($_SESSION);
    session_destroy();
    header('Location: session_timeout_message.php');
    exit;
}

$_SESSION['lastAct'] = time();

并在您的页面中添加(可选,无论页面是否刷新,用户都将被注销(因为他在下一页日志中注销)。)

<meta http-equiv="refresh" content="1801;" /> 

答案 9 :(得分:0)

如果您担心在登录超时后丢失了用户的信息;另一种选择是在打开新会话时简单地存储所有发布的信息(当服务器关闭/报废旧会话时,将始终启动新会话)路由到日志页面。如果用户成功登录,则可以使用此保存的信息将用户返回到他所在的位置。这样,即使用户离开几个小时,他也可以在成功登录后返回原来的位置;没有丢失任何信息。

这需要程序员做更多的工作,但这是一个非常受用户赞赏的功能。他们特别欣赏这样一个事实,即他们可以完全专注于他们必须做的事情,而不会强调每30分钟左右可能丢失他们的信息。