使用系统时钟进行准确的空闲超时警告

时间:2016-06-03 15:53:34

标签: javascript jquery

我正在开发一个模式,它会因空闲时间提醒用户注册挂起。总的来说它有效,但我注意到计时器不是100%准确。我知道setInterval和准确性存在问题。我仍然看到差异,并欢迎提出如何改进我的代码的建议。

var sessionTimeoutPeriod = 240;
var state = "L";
var timeoutPeriod = sessionTimeoutPeriod * 1000;
var logout = Math.floor(timeoutPeriod / 60000);
var idleInterval;

if (state == "L" || state == "O" || state == "C") {
var idleTime = 0;

$(document).ready(function() {
    //Zero the idle timer on mouse movement.
    $(this).mousemove(function(e) {
        idleTime = 0;
        console.log("The mouse moved, idle time = " + idleTime);
    });
    $(this).keypress(function(e) {
        idleTime = 0;
        console.log("A key was pressed, idle time = " + idleTime);
    });


    idleInterval = setInterval(timerIncrement, 60000); // 1 minute

});

function timerIncrement() {

  idleTime++;
    console.log("The total idle time is "+idleTime+  " minutes.");

    if (idleTime >= 1) {
    console.log("The modal will fire if idle time = " +idleTime);
        var modal = new window.AccessibleModal({
        mainPage: $('#main'),
            overlay: $('#overlay').css('display', 'block'),
            modal: $('#modal-session-timeout'),
            prevFocus: $('#main')
        });

         modal.show();

         $('#modal-overlay').removeClass('opened');

        $('.js-timeout-refresh, .xClose').click(function() {
            modal.hide();
            $('#overlayTY').css('display', 'none');
            idleTime = 0;

            console.log("The total idle time is "+idleTime+  " minutes.");
        });
        $('.js-timeout-session-end').click(function() {
            modal.hide();
            $('#overlay').css('display', 'none');
            endSession();
        });
        console.log(idleTime);
    }
    if (idleTime == logout) { // 9 minutes
        endSession();
    }

    var endSession = function() {
        document.location.replace(logoutPageUrl);
    };
}

}

2 个答案:

答案 0 :(得分:1)

您可以通过比较当前时间与自上次活动以来的时间来验证手动传递的时间,而不是依赖间隔来确定已经过了多少时间。

这样,您可以增加检查间隔,而无需修改代码。差异永远不会高于现在的间隔超时,差异也不会逐渐变化,它总是低于或等于间隔(在最坏的情况下)。

这是一个基本的例子。

var sessionTimeoutPeriod = 240;
var timeoutPeriod = sessionTimeoutPeriod * 1000;
var oneMinute = 60000;
var showIdlePopUpTimeOut = oneMinute * 2;
var lastActivity = new Date();

function getIdleTime() {
    return new Date().getTime() - lastActivity.getTime();
}

$(document).ready(function () {
    //Zero the idle timer on mouse movement.
    $(this).mousemove(function (e) {
        console.log("The mouse moved, idle time = " + getIdleTime());
        lastActivity = new Date();
    });
    $(this).keypress(function (e) {
        console.log("A key was pressed, idle time = " + getIdleTime());
        lastActivity = new Date();
    });

    setInterval(checkIdleTime, 5000);
});

function endSession() {
    document.location.replace(logoutPageUrl);
};

function checkIdleTime() {
    var idleTime = getIdleTime();
    console.log("The total idle time is " + idleTime / oneMinute + " minutes.");

    if (idleTime > showIdlePopUpTimeOut) {
        var modal = new window.AccessibleModal({
            mainPage: $('#main'),
            overlay: $('#overlay').css('display', 'block'),
            modal: $('#modal-session-timeout'),
            prevFocus: $('#main')
        });

        modal.show();

        $('#modal-overlay').removeClass('opened');

        $('.js-timeout-refresh, .xClose').click(function () {
            modal.hide();
            $('#overlayTY').css('display', 'none');
            lastActivity = new Date();
        });
        $('.js-timeout-session-end').click(function () {
            modal.hide();
            $('#overlay').css('display', 'none');
            endSession();
        });
        console.log(lastActivity);
    }
    if (idleTime > timeoutPeriod) { // 4 minutes
        endSession();
    }

}

答案 1 :(得分:-1)

问题在于你的功能" timerIncrement"加载页面后每分钟检查差异,因此在上次活动后1分钟内永远不会得到确切的结果。从60000到1000的间隔时间将解决问题。

你甚至不需要计算差异,你可以在每次活动时重置超时。像这样:

$(this).on("mousemove keypress", function(e) {
        clearInterval(idleInterval);
        idleInterval = setTimeout(functionThatExecutesAfter1minInactivity, 60000);
    });