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



我正在研究一种模式,该模式将提醒用户由于空闲时间而挂起的注销。 总的来说,它可以工作,但我注意到计时器不是 100% 准确的。 我知道设置间隔和准确性存在问题。 我仍然看到差异,并欢迎有关如何改进我的代码的建议。

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);
    };
}

}

您可以通过

将当前时间与自上次活动以来的时间进行比较来手动验证已经过去了多少时间,而不是依靠间隔来确定过去了多少时间。

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

下面是一个基本示例。

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();
    }
}

问题是您的函数"timerIncrement"在加载页面后每分钟检查一次差异,因此您将永远不会在上次活动后获得准确的 1 分钟。将间隔从 60000 更改为 1000 将解决此问题。

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

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

最新更新