如何知道浏览器空闲时间?

时间:2012-03-05 09:52:48

标签: javascript browser

如何跟踪浏览器的空闲时间?我正在使用IE8。

我没有使用任何会话管理,也不想在服务器端处理它。

5 个答案:

答案 0 :(得分:65)

以下是纯JavaScript方式来跟踪空闲时间以及达到某个限制时执行某些操作:

var IDLE_TIMEOUT = 60; //seconds
var _idleSecondsTimer = null;
var _idleSecondsCounter = 0;

document.onclick = function() {
    _idleSecondsCounter = 0;
};

document.onmousemove = function() {
    _idleSecondsCounter = 0;
};

document.onkeypress = function() {
    _idleSecondsCounter = 0;
};

_idleSecondsTimer = window.setInterval(CheckIdleTime, 1000);

function CheckIdleTime() {
     _idleSecondsCounter++;
     var oPanel = document.getElementById("SecondsUntilExpire");
     if (oPanel)
         oPanel.innerHTML = (IDLE_TIMEOUT - _idleSecondsCounter) + "";
    if (_idleSecondsCounter >= IDLE_TIMEOUT) {
        window.clearInterval(_idleSecondsTimer);
        alert("Time expired!");
        document.location.href = "logout.html";
    }
}
#SecondsUntilExpire { background-color: yellow; }
You will be auto logged out in <span id="SecondsUntilExpire"></span> seconds.

此代码将在显示警报和重定向之前等待60秒,任何操作都将“重置”计数 - 鼠标单击,鼠标移动或按键。

它应该尽可能地跨浏览器,并且直截了当。如果您向ID为SecondsUntilExpire的网页添加元素,它还支持显示剩余时间。

上述代码应该可以正常工作,但有几个缺点,例如:它不允许任何其他事件运行,也不支持乘法选项卡。包含这两者的重构代码如下:(无需更改HTML)

var IDLE_TIMEOUT = 60; //seconds
var _localStorageKey = 'global_countdown_last_reset_timestamp';
var _idleSecondsTimer = null;
var _lastResetTimeStamp = (new Date()).getTime();
var _localStorage = null;

AttachEvent(document, 'click', ResetTime);
AttachEvent(document, 'mousemove', ResetTime);
AttachEvent(document, 'keypress', ResetTime);
AttachEvent(window, 'load', ResetTime);

try {
    _localStorage = window.localStorage;
}
catch (ex) {
}

_idleSecondsTimer = window.setInterval(CheckIdleTime, 1000);

function GetLastResetTimeStamp() {
    var lastResetTimeStamp = 0;
    if (_localStorage) {
        lastResetTimeStamp = parseInt(_localStorage[_localStorageKey], 10);
        if (isNaN(lastResetTimeStamp) || lastResetTimeStamp < 0)
            lastResetTimeStamp = (new Date()).getTime();
    } else {
        lastResetTimeStamp = _lastResetTimeStamp;
    }

    return lastResetTimeStamp;
}

function SetLastResetTimeStamp(timeStamp) {
    if (_localStorage) {
        _localStorage[_localStorageKey] = timeStamp;
    } else {
        _lastResetTimeStamp = timeStamp;
    }
}

function ResetTime() {
    SetLastResetTimeStamp((new Date()).getTime());
}

function AttachEvent(element, eventName, eventHandler) {
    if (element.addEventListener) {
        element.addEventListener(eventName, eventHandler, false);
        return true;
    } else if (element.attachEvent) {
        element.attachEvent('on' + eventName, eventHandler);
        return true;
    } else {
        //nothing to do, browser too old or non standard anyway
        return false;
    }
}

function WriteProgress(msg) {
    var oPanel = document.getElementById("SecondsUntilExpire");
    if (oPanel)
         oPanel.innerHTML = msg;
    else if (console)
        console.log(msg);
}

function CheckIdleTime() {
    var currentTimeStamp = (new Date()).getTime();
    var lastResetTimeStamp = GetLastResetTimeStamp();
    var secondsDiff = Math.floor((currentTimeStamp - lastResetTimeStamp) / 1000);
    if (secondsDiff <= 0) {
        ResetTime();
        secondsDiff = 0;
    }
    WriteProgress((IDLE_TIMEOUT - secondsDiff) + "");
    if (secondsDiff >= IDLE_TIMEOUT) {
        window.clearInterval(_idleSecondsTimer);
        ResetTime();
        alert("Time expired!");
        document.location.href = "logout.html";
    }
}

上面重构的代码使用本地存储来跟踪计数器上次重置的时间,并在每个打开的包含代码的新选项卡上重置它,然后所有选项卡的计数器都相同,并且重置为一个将导致所有选项卡重置。由于Stack Snippets不允许本地存储,因此在那里托管它是没有意义的,所以我做了一个小提琴: http://jsfiddle.net/yahavbr/gpvqa0fj/3/

答案 1 :(得分:3)

希望这就是你要找的东西 jquery-idletimer-plugin

答案 2 :(得分:3)

回复太迟了,但这可能有助于有人写出干净实用的解决方案。当您不需要显示会话到期时间时,这是一个理想的解决方案。很高兴忽略setInterval(),它会在整个应用程序运行时间内继续运行脚本。

    var inactivityTimeOut = 10 * 1000, //10 seconds
        inactivitySessionExpireTimeOut = '';

    setSessionExpireTimeOut();

    function setSessionExpireTimeOut () {
        'use strict';
        
        clearSessionExpireTimeout();
        inactivitySessionExpireTimeOut = setTimeout(function() {
            expireSessionIdleTime();
        }, inactivityTimeOut);
    }

    function expireSessionIdleTime () {
        'use strict';

        console.log('user inactive for ' + inactivityTimeOut + " seconds");
        console.log('session expired');
        alert('time expired');
        clearSessionExpireTimeout();
        document.location.href = "logout.html";
    }

    function clearSessionExpireTimeout () {
            'use strict';

            clearTimeout(inactivitySessionExpireTimeOut);
    }
Running example: Timeout alert will be popped up in 10 seconds

答案 3 :(得分:1)

这是一种使用jquery的方法,因为我需要在文档上保留现有的键盘事件。

我还需要在不同的空闲时间做不同的事情,所以我把它包装在一个函数

var onIdle = function (timeOutSeconds,func){
    //Idle detection
    var idleTimeout;
    var activity=function() {
        clearTimeout(idleTimeout);
        console.log('to cleared');
        idleTimeout = setTimeout(func, timeOutSeconds * 1000);
    }
    $(document).on('mousedown mousemove keypress',activity);
    activity();
}
onIdle(60*60,function(){
    location.reload();
});
onIdle(30,function(){
    if(currentView!=='welcome'){
        loadView('welcome');
    }
});

答案 4 :(得分:1)

我需要类似的东西并创建了这个:https://github.com/harunurhan/idlejs

它在某种程度上简单,可配置且功能强大,没有任何依赖性。这是一个例子。

import { Idle } from 'idlejs/dist';

// with predefined events on `document`
const idle = new Idle()
  .whenNotInteractive()
  .within(60)
  .do(() => console.log('IDLE'))
  .start();

您还可以使用自定义事件目标和事件

const idle = new Idle()
  .whenNot([{
    events: ['click', 'hover'],
    target: buttonEl,
  },
  {
    events: ['click', 'input'],
    target: inputEl,
  },
  ])
  .within(10)
  .do(() => called = true)
  .start();

(用打字稿编写并编译成es5)