是否有可能在JavaScript中检测“空闲”时间?
我的主要用例可能是预取或预加载内容。
我将空闲时间定义为用户不活动或没有任何CPU使用的时间段
是否有可能在JavaScript中检测“空闲”时间?
我的主要用例可能是预取或预加载内容。
我将空闲时间定义为用户不活动或没有任何CPU使用的时间段
当前回答
我终于把这个工作在我的网站。我发现equiman的回答最有帮助。这个答案的问题是JavaScript中的alert()函数会暂停脚本执行。如果您像我一样希望发送一个警报,然后如果没有收到响应,站点将自动注销,那么暂停执行是一个问题。
解决方案是用自定义除法替换alert(),如下所述。
下面是代码:(注意:您需要更改第58行以重定向到您的站点的适当URL)
var inactivityTracker = function () { // Create an alert division var alertDiv = document.createElement("div"); alertDiv.setAttribute("style","position: absolute;top: 30%;left: 42.5%;width: 200px;height: 37px;background-color: red;text-align: center; color:white"); alertDiv.innerHTML = "You will be logged out in 5 seconds!!"; // Initialise a variable to store an alert and logout timer var alertTimer; var logoutTimer; // Set the timer thresholds in seconds var alertThreshold = 3; var logoutThreshold = 5; // Start the timer window.onload = resetAlertTimer; // Ensure timer resets when activity logged registerActivityLoggers(resetAlertTimer); // ***** FUNCTIONS ***** // // Function to register activities for alerts function registerActivityLoggers(functionToCall) { document.onmousemove = functionToCall; document.onkeypress = functionToCall; } // Function to reset the alert timer function resetAlertTimer() { clearTimeout(alertTimer); alertTimer = setTimeout(sendAlert, alertThreshold * 1000); } // Function to start logout timer function startLogoutTimer() { clearTimeout(logoutTimer); logoutTimer = setTimeout(logout, logoutThreshold * 1000); } // Function to logout function sendAlert() { // Send a logout alert document.body.appendChild(alertDiv); // Start the logout timer startLogoutTimer(); // Reset everything if an activity is logged registerActivityLoggers(reset); } // Function to logout function logout(){ //location.href = 'index.php'; } // Function to remove alert and reset logout timer function reset(){ // Remove alert division alertDiv.parentNode.removeChild(alertDiv); // Clear the logout timer clearTimeout(logoutTimer); // Restart the alert timer document.onmousemove = resetAlertTimer; document.onkeypress = resetAlertTimer; } }; <html> <script type="text/javascript" src="js/inactivityAlert.js"></script> <head> <title>Testing an inactivity timer</title> </head> <body onload="inactivityTracker();" > Testing an inactivity timer </body> </html>
其他回答
我的回答受到了维贾伊的启发,但我认为这是一个更简短、更普遍的解决方案,我想把它分享给可能有帮助的人。
(function () {
var minutes = true; // change to false if you'd rather use seconds
var interval = minutes ? 60000 : 1000;
var IDLE_TIMEOUT = 3; // 3 minutes in this example
var idleCounter = 0;
document.onmousemove = document.onkeypress = function () {
idleCounter = 0;
};
window.setInterval(function () {
if (++idleCounter >= IDLE_TIMEOUT) {
window.location.reload(); // or whatever you want to do
}
}, interval);
}());
按照目前的情况,这段代码将立即执行,并在3分钟内没有鼠标移动或按键后重新加载当前页面。
它利用普通的JavaScript和立即调用的函数表达式以一种干净且自包含的方式处理空闲超时。
试试这段代码。它工作得很完美。
var IDLE_TIMEOUT = 10; //seconds
var _idleSecondsCounter = 0;
document.onclick = function () {
_idleSecondsCounter = 0;
};
document.onmousemove = function () {
_idleSecondsCounter = 0;
};
document.onkeypress = function () {
_idleSecondsCounter = 0;
};
window.setInterval(CheckIdleTime, 1000);
function CheckIdleTime() {
_idleSecondsCounter++;
var oPanel = document.getElementById("SecondsUntilExpire");
if (oPanel)
oPanel.innerHTML = (IDLE_TIMEOUT - _idleSecondsCounter) + "";
if (_idleSecondsCounter >= IDLE_TIMEOUT) {
alert("Time expired!");
document.location.href = "SessionExpired.aspx";
}
}
(部分灵感来自Equiman回答的良好核心逻辑。)
sessionExpiration.js
sessionExpiration.js是轻量级的,但有效和可定制的。一旦实现,只在一行中使用:
sessionExpiration(idleMinutes, warningMinutes, logoutUrl);
Affects all tabs of the browser, not just one. Written in pure JavaScript, with no dependencies. Fully client side. (If so wanted.) Has warning banner and countdown clock, that is cancelled by user interaction. Simply include the sessionExpiration.js, and call the function, with arguments [1] number of idle minutes (across all tabs) until user is logged out, [2] number of idle minutes until warning and countdown is displayed, and [3] logout url. Put the CSS in your stylesheet. Customize it if you like. (Or skip and delete banner if you don't want it.) If you do want the warning banner however, then you must put an empty div with ID sessExpirDiv on your page (a suggestion is putting it in the footer). Now the user will be logged out automatically if all tabs have been inactive for the given duration. Optional: You may provide a fourth argument (URL serverRefresh) to the function, so that a server side session timer is also refreshed when you interact with the page.
这是一个例子,如果你不改变CSS,它看起来是什么样子的。
下面是一个在Angular中完成的AngularJS服务。
/* Tracks now long a user has been idle. secondsIdle can be polled
at any time to know how long user has been idle. */
fuelServices.factory('idleChecker',['$interval', function($interval){
var self = {
secondsIdle: 0,
init: function(){
$(document).mousemove(function (e) {
self.secondsIdle = 0;
});
$(document).keypress(function (e) {
self.secondsIdle = 0;
});
$interval(function(){
self.secondsIdle += 1;
}, 1000)
}
}
return self;
}]);
请记住,这个空闲检查器将为所有路由运行,因此应该在angular应用程序加载时在.run()中初始化它。然后你可以使用idleChecker。在每个路由内的secondside。
myApp.run(['idleChecker',function(idleChecker){
idleChecker.init();
}]);
尝试freddoo的解决方案,但它在1分钟超时时间内不起作用,所以我稍微改变了它,以记录用户最后一次点击页面的日期+时间,在我的timerIncrement函数中,我计算当前时间和最后一次点击时间之间的差异,如果该值恰好大于或等于超时值,那么我重定向:
var clickedDate = new Date();
var idleTime = 1; //
function timerIncrement() {
var nowDate = new Date();
var diffMs = (nowDate - clickedDate); //Milliseconds between now & the last time a user clicked somewhere on the page
var diffMins = Math.round(((diffMs % 86400000) % 3600000) / 60000); //Convert ms to minutes
if (diffMins >= idleTime) {
//Redirect user to home page etc...
}
}
$(document).ready(function () {
var idleInterval = setInterval(timerIncrement, 60000); // 1 minute
$(this).click(function (e) {
clickedDate = new Date();
});
});