【发布时间】:2018-03-13 18:48:52
【问题描述】:
我尝试创建 JS 函数,该函数应该跟踪用户活动并在用户处于非活动状态时显示警告模式框。功能将在页面加载时启动。一些变量是全局变量,我使用它们来设置会话分钟数并将用户活动保持在屏幕上。只需计算用户会话的时间并减去出现警告之前的秒数。如果用户在页面主体上处于活动状态,我会将 JS 日期对象保存在全局变量中。一旦计时器降至 0,我将重置将注销用户并重定向到登录页面的时间或触发功能。我的代码中出现了一个问题,如果用户扩展会话(只需单击模态框中的继续按钮)计时器应该重新启动并且该部分工作正常。计时器重新启动计数和一旦达到 0 警告应该再次显示,而不是我的 expierIn 变量返回负数。我将任何等于或小于零的数字设置为 0。所以我的会话自动结束。这是错误的,我不确定为什么我的数学第二次返回负数。这是我的代码的工作示例。我没有包含应该向服务器发送 ping 以保持服务器端会话活动的 Ajax 调用。
$(document).ready(function(){
TimeOut(); // Call session timeout function.
});
/*** Start: Session Timeout Handling(The following functions are part of session handling). ***/
var sessionMinutes = 4; // Session time in minutes.
var dmSessionBox; // Session timeout warning box
var lastActivity = null; // keeps track of user last activity
var timeout = null; // keeps timeout value
var secondsToShowDialog = 120; // number of seconds until modal shows on the screen
var dialogShowing = false; // flag to show/hide modal
var nextPoll = false; // flag to set next timeout
var lastHist = new Date(); // first time user logged to the system.
log('lastHit: '+lastHist.toLocaleTimeString());
function TimeOut() {
if (sessionMinutes) {
dmSessionBox = $('<div id="sessiontimeoutwarning" class="modal fade" role="dialog"><div class="modal-dialog modal-lg"><div class="modal-content"> <div class="modal-header"><h2 class="modal-title warning"><span class="glyphicon glyphicon-warning-sign"></span>Your session is about to expire</h2></div> <div class="modal-body"><div class="alert alert-warning warning"> <strong>Warning!</strong>Click the Continue button to extend your session. </div></div><div class="modal-footer"><button type="button" id="continueButton" class="btn btn-primary" data-dismiss="modal">Continue</button</div>/div>/div>/div>');
$(document.body).append(dmSessionBox);
$('body').on('mousedown keydown', function(event) {
lastActivity = new Date();
});
var sessionSeconds = sessionMinutes * 60; // Convert session minutes in seconds.
log("Init - session is set to expire in " + sessionSeconds + " seconds at " + new Date(new Date().getTime() + (sessionSeconds*1000)).toLocaleTimeString());
receiveUpdatedTimeRemaining(sessionSeconds);
}
}
function receiveUpdatedTimeRemaining(timeout) {
if (nextPoll)
clearTimeout(nextPoll);
var wakeUpMillis;
if (timeout <= (secondsToShowDialog)) {
if (!dialogShowing)
lastActivity !== null ? getTimeout() : showTimeoutDialog(true);
wakeUpMillis = 30 * 1000;
}else{
showTimeoutDialog(false);
dialogShowing = false;
wakeUpMillis = (timeout * 1000) - (secondsToShowDialog * 1000);
}
log("receiveUpdatedTimeRemaining - Wake up in " + parseInt(wakeUpMillis/1000) + " for new timeout");
nextPoll = setTimeout(getTimeout, wakeUpMillis);
}
function getTimeout() {
clearTimeout(nextPoll);
var currentTime = new Date().getTime(),
lastClick = lastActivity !== null ? lastActivity.getTime() : lastHist.getTime(),
secondsPassed = (currentTime - lastClick) / 1000, // Elapsed number of seconds since last user activity.
totalSeconds = sessionMinutes * 60, // Total number of seconds for this session
expierIn = totalSeconds - secondsPassed;
log('expierIn: '+expierIn);
timeout = expierIn <= 0 ? 0 : expierIn; // Set time in timeout variable
timeout == 0 ? showTimeoutErrorDialog() : receiveUpdatedTimeRemaining(timeout);
lastActivity = null; // Reset lastActivity
}
function showTimeoutDialog(showIt) {
dmSessionBox.find('#continueButton').on('click', function() {
lastActivity = new Date();
getTimeout();
});
showIt ? $('#sessiontimeoutwarning').modal('show') : $('#sessiontimeoutwarning').modal('hide');
dialogShowing = true;
}
function showTimeoutErrorDialog() {
$('#sessiontimeoutwarning').modal('hide'); // Close modal box
log('Session timed out.')
}
function log(msg){
if (window.console && console.log)
console.log(new Date().toLocaleTimeString() + " :: " + msg);
}
/*** End: Session timeout handling. ***/
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<html>
<head>
<title>Session Timeout Test</title>
</head>
<body>
<div>My App</div>
</body>
</html>
在显示警告后,我单击继续会话将再延长 240 秒,并且警告的唤醒呼叫设置为 120 秒,但模式会话将结束而不是显示。我不确定我的变量是否没有覆盖以前的值或者我的代码中有其他错误。
【问题讨论】:
-
请使用
if块而不是未分配的三元组,例如timeout == 0 ? showTimeoutErrorDialog() : receiveUpdatedTimeRemaining(timeout),这不聪明,您的代码很难阅读/理解。 -
@James 我不确定为什么 if/else 块比三元运算符更好?准备好特定的代码行有多难?
-
@espresso_coffee 我相信评论更多的是关于使用三元进行逻辑分支而不是其预期的赋值用途,因为它返回一个值,而不是它的可读性。通常不赞成将其用于逻辑代码分支。
标签: javascript jquery session twitter-bootstrap-3 timer