是否有可能在JavaScript中检测“空闲”时间?
我的主要用例可能是预取或预加载内容。
我将空闲时间定义为用户不活动或没有任何CPU使用的时间段
是否有可能在JavaScript中检测“空闲”时间?
我的主要用例可能是预取或预加载内容。
我将空闲时间定义为用户不活动或没有任何CPU使用的时间段
当前回答
你肯定想知道window.requestIdleCallback(),它在浏览器空闲期间对要调用的函数进行排队。
您可以在Quicklink repo中看到这个API的优雅用法。
const requestIdleCallback = window.requestIdleCallback ||
function (cb) {
const start = Date.now();
return setTimeout(function () {
cb({
didTimeout: false,
timeRemaining: function () {
return Math.max(0, 50 - (Date.now() - start));
},
});
}, 1);
};
上面代码的意思是:如果浏览器支持requestIdleCallback(检查兼容性),就使用它。如果不支持,则使用setTimeout(()=>{}, 1)作为回退,它应该在事件循环结束时将被调用的函数排队。
然后你可以这样使用它:
requestIdleCallback(() => {...}, {
timeout: 2000
});
第二个参数是可选的,如果希望确保函数执行,则可能需要设置一个超时。
其他回答
纯JavaScript,通过addEventListener正确设置重置时间和绑定:
(function() {
var t,
timeout = 5000;
function resetTimer() {
console.log("reset: " + new Date().toLocaleString());
if (t) {
window.clearTimeout(t);
}
t = window.setTimeout(logout, timeout);
}
function logout() {
console.log("done: " + new Date().toLocaleString());
}
resetTimer();
//And bind the events to call `resetTimer()`
["click", "mousemove", "keypress"].forEach(function(name) {
console.log(name);
document.addEventListener(name, resetTimer);
});
}());
我写了一个简单的jQuery插件,将做什么你正在寻找。
https://github.com/afklondon/jquery.inactivity
$(document).inactivity( {
interval: 1000, // the timeout until the inactivity event fire [default: 3000]
mouse: true, // listen for mouse inactivity [default: true]
keyboard: false, // listen for keyboard inactivity [default: true]
touch: false, // listen for touch inactivity [default: true]
customEvents: "customEventName", // listen for custom events [default: ""]
triggerAll: true, // if set to false only the first "activity" event will be fired [default: false]
});
脚本将监听鼠标,键盘,触摸和其他自定义事件不活动(空闲),并触发全局“活动”和“不活动”事件。
下面是tvanfosson的想法的粗略jQuery实现:
$(document).ready(function(){
idleTime = 0;
//Increment the idle time counter every second.
var idleInterval = setInterval(timerIncrement, 1000);
function timerIncrement()
{
idleTime++;
if (idleTime > 2)
{
doPreload();
}
}
//Zero the idle timer on mouse movement.
$(this).mousemove(function(e){
idleTime = 0;
});
function doPreload()
{
//Preload images, etc.
}
})
我使用这种方法,因为您不需要在事件触发时不断重置时间。相反,我们只记录时间,这将生成空闲的起始点。
function idle(WAIT_FOR_MINS, cb_isIdle) {
var self = this,
idle,
ms = (WAIT_FOR_MINS || 1) * 60000,
lastDigest = new Date(),
watch;
//document.onmousemove = digest;
document.onkeypress = digest;
document.onclick = digest;
function digest() {
lastDigest = new Date();
}
// 1000 milisec = 1 sec
watch = setInterval(function() {
if (new Date() - lastDigest > ms && cb_isIdel) {
clearInterval(watch);
cb_isIdle();
}
}, 1000*60);
},
试试这段代码。它工作得很完美。
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";
}
}