是否有可能在JavaScript中检测“空闲”时间?
我的主要用例可能是预取或预加载内容。
我将空闲时间定义为用户不活动或没有任何CPU使用的时间段
是否有可能在JavaScript中检测“空闲”时间?
我的主要用例可能是预取或预加载内容。
我将空闲时间定义为用户不活动或没有任何CPU使用的时间段
当前回答
您要求优雅,我创建了一个简单的类来支持惰性检查(具有空闲状态),除了命令方式(带有回调)之外。此外,当违反空闲时间时,该类支持“backToActive”。
class Idle {
constructor(timeout = 10, idleCallback = null, backToActiveCallback = null, autoStart = true, backToActiveOnXHR = false) {
this.timeout = timeout
this.idleCallback = idleCallback
this.backToActiveCallback = backToActiveCallback
this.autoStart = autoStart // only F5
this.backToActiveOnXHR = backToActiveOnXHR
this.idle = false
this.timer = null
this.events = ['scroll', 'mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart']
this.init()
}
init() {
if(this.backToActiveOnXHR) {
this.events.push('load')
}
this.events.forEach(name => {
window.addEventListener(name, this.backToActive, true)
})
if(this.autoStart) {
this.backToActive()
}
}
goIdle = () => {
this.idle = true
if(!!this.idleCallback) {
this.idleCallback(this.timeout)
}
}
backToActive = () => {
if(this.idle) {
this.backToActiveCallback()
}
this.idle = false
clearTimeout(this.timer)
this.timer = setTimeout(this.goIdle, this.timeout * 1000)
}
}
用法:
let idleCallback = timeout => { console.log(`Went idle after ${timeout} seconds`) }
let backToActiveCallback = () => { console.log('Back to active') }
let idle = new Idle(30, idleCallback, backToActiveCallback)
devtools的结果:
// Went idle after 30 seconds <--- goes idle when no activity is detected
// Back to active <--- when the user is detected again
支持懒惰的好处:
setInterval(() => {
common.fetchApi('/api/v1/list', { status: idle.idle ? 'away' : 'online' }).then(/* show a list of elements */)
}, 1000 * 5)
你为什么要一张惰性支票?有时我们使用周期性的XHR(带setInterval),即当用户观看航班、乘车、电影、订单等列表时。对于每个XHR,我们可以添加关于他/她的活动状态(在线/离开)的信息,这样我们就可以了解系统中的活跃用户。
我的课程是基于Equiman和Frank Conijn的回答。
其他回答
我终于把这个工作在我的网站。我发现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>
改进Equiman(原始)的答案:
function idleLogout() {
var t;
window.onload = resetTimer;
window.onmousemove = resetTimer;
window.onmousedown = resetTimer; // catches touchscreen presses as well
window.ontouchstart = resetTimer; // catches touchscreen swipes as well
window.ontouchmove = resetTimer; // required by some devices
window.onclick = resetTimer; // catches touchpad clicks as well
window.onkeydown = resetTimer;
window.addEventListener('scroll', resetTimer, true); // improved; see comments
function yourFunction() {
// your function for too long inactivity goes here
// e.g. window.location.href = 'logout.php';
}
function resetTimer() {
clearTimeout(t);
t = setTimeout(yourFunction, 10000); // time is in milliseconds
}
}
idleLogout();
除了活动检测方面的改进,以及从文档到窗口的更改之外,这个脚本实际上调用了函数,而不是让它闲置着。
它不会直接捕获零CPU使用情况,但这是不可能的,因为执行函数会导致CPU使用。用户不活动最终导致CPU使用率为零,因此它间接地捕捉到CPU使用率为零。
JavaScript没有办法告诉CPU的使用情况。这将打破运行在沙盒中的JavaScript。
除此之外,连接页面的onmouseover和onkeydown事件可能会工作。
你也可以在onload事件中使用setTimeout来调度延迟后调用的函数。
// Call aFunction after 1 second
window.setTimeout(aFunction, 1000);
尝试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();
});
});
<script type="text/javascript">
var idleTime = 0;
$(document).ready(function () {
//Increment the idle time counter every minute.
idleInterval = setInterval(timerIncrement, 60000); // 1 minute
//Zero the idle timer on mouse movement.
$('body').mousemove(function (e) {
//alert("mouse moved" + idleTime);
idleTime = 0;
});
$('body').keypress(function (e) {
//alert("keypressed" + idleTime);
idleTime = 0;
});
$('body').click(function() {
//alert("mouse moved" + idleTime);
idleTime = 0;
});
});
function timerIncrement() {
idleTime = idleTime + 1;
if (idleTime > 10) { // 10 minutes
window.location.assign("http://www.google.com");
}
}
</script>
我认为这个jQuery代码是一个完美的,虽然复制和修改从上面的答案!!
不要忘记在你的文件中包含jQuery库!