如何优雅地检测JavaScript中的空闲时间
是否可以在JavaScript中检测“空闲时间” 我的主要用例可能是预取或预加载内容如何优雅地检测JavaScript中的空闲时间,javascript,Javascript,是否可以在JavaScript中检测“空闲时间” 我的主要用例可能是预取或预加载内容 空闲时间:用户处于非活动状态或不使用任何CPU的时间是否可以每10秒运行一次函数,并检查一个“计数器”变量?如果可能的话,你可以在页面上放一个鼠标盖,不是吗 如果是,请使用mouseover事件重置“counter”变量。如果调用了函数,并且计数器超出了预先确定的范围,则执行操作。通过检测窗体主体上的鼠标移动并用最后一次移动时间更新全局变量,您可能可以将一些内容组合在一起。然后,您需要运行一个间隔计时器,定期检
空闲时间:用户处于非活动状态或不使用任何CPU的时间是否可以每10秒运行一次函数,并检查一个“计数器”变量?如果可能的话,你可以在页面上放一个鼠标盖,不是吗
如果是,请使用mouseover事件重置“counter”变量。如果调用了函数,并且计数器超出了预先确定的范围,则执行操作。通过检测窗体主体上的鼠标移动并用最后一次移动时间更新全局变量,您可能可以将一些内容组合在一起。然后,您需要运行一个间隔计时器,定期检查上次移动时间,并在检测到上次鼠标移动后足够长的时间内执行操作。下面是一个粗略的jQuery实现:
您可能会使用列出的mousemove技巧检测网页上的不活动,但这不会告诉您该用户不在另一个窗口或选项卡的另一个页面上,或者该用户在或中,或者只是此时没有查看您的页面 一般来说,我只做预回迁,依靠客户端的多任务处理。如果你真的需要这个功能,你可以在Windows中使用一个控件来做一些事情,但它最多也很难看。类似于(使用jQuery自定义事件)
文件jquery-idle-detect.js
(函数($,$w){
//公开配置选项
//在2秒钟内没有事件时触发Idle
$.idleTimeout=2000;
//当前处于空闲状态
var idle=false;
//用于检测的空闲计时器的句柄
var idleTimer=null;
//启动空闲计时器并在加载时绑定事件(未准备好DOM)
$w.on('load',function(){
startIdleTimer();
$w.on('focus resize mousemove keyup',StartItemer)
.on('blur',idleStart)//在不同选项卡/窗口中强制空闲
;
]);
函数startIdleTimer(){
clearTimeout(idleTimer);//清除前一个计时器
if(idle)$w.trigger('idle:stop');//如果空闲,发送停止事件
idle=false;//不空闲
var timeout=~~$.idleTimeout;//选项为整数
如果(超时300000)
超时=300000;//最多5分钟
idleTimer=setTimeout(idleStart,timeout);//新计时器
}
函数idleStart(){
如果(!空闲)
$w.trigger('idle:start');
空闲=真;
}
}(window.jQuery,window.jQuery(window)))
下面是一个使用jQuery处理mousemove和keypress事件的简单脚本。
如果时间到期,页面将重新加载
<script type="text/javascript">
var idleTime = 0;
$(document).ready(function () {
// Increment the idle time counter every minute.
var idleInterval = setInterval(timerIncrement, 60000); // 1 minute
// Zero the idle timer on mouse movement.
$(this).mousemove(function (e) {
idleTime = 0;
});
$(this).keypress(function (e) {
idleTime = 0;
});
});
function timerIncrement() {
idleTime = idleTime + 1;
if (idleTime > 19) { // 20 minutes
window.location.reload();
}
}
</script>
var-idleTime=0;
$(文档).ready(函数(){
//每分钟增加一次空闲时间计数器。
var idleInterval=setInterval(timerIncrement,60000);//1分钟
//将鼠标移动时的空闲计时器归零。
$(this).mousemove(函数(e){
空闲时间=0;
});
$(此)。按键(功能(e){
空闲时间=0;
});
});
函数timerIncrement(){
空闲时间=空闲时间+1;
如果(空闲时间>19){//20分钟
window.location.reload();
}
}
在不使用jQuery的情况下,仅使用普通JavaScript:
var inactivityTime = function () {
var time;
window.onload = resetTimer;
// DOM Events
document.onmousemove = resetTimer;
document.onkeydown = resetTimer;
function logout() {
alert("You are now logged out.")
//location.href = 'logout.html'
}
function resetTimer() {
clearTimeout(time);
time = setTimeout(logout, 3000)
// 1000 milliseconds = 1 second
}
};
idleTimer = null;
idleState = false;
idleWait = 2000;
(function ($) {
$(document).ready(function () {
$('*').bind('mousemove keydown scroll', function () {
clearTimeout(idleTimer);
if (idleState == true) {
// Reactivated event
$("body").append("<p>Welcome Back.</p>");
}
idleState = false;
idleTimer = setTimeout(function () {
// Idle Event
$("body").append("<p>You've been idle for " + idleWait/1000 + " seconds.</p>");
idleState = true; }, idleWait);
});
$("body").trigger("mousemove");
});
}) (jQuery)
并在需要的地方初始化函数(例如:onPageLoad)
如果需要,可以添加更多DOM事件。常用的有:
document.onload = resetTimer;
document.onmousemove = resetTimer;
document.onmousedown = resetTimer; // touchscreen presses
document.ontouchstart = resetTimer;
document.onclick = resetTimer; // touchpad clicks
document.onkeydown = resetTimer; // onkeypress is deprectaed
document.addEventListener('scroll', resetTimer, true); // improved; see comments
或使用数组注册所需的事件
window.addEventListener('load', resetTimer, true);
var events = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart'];
events.forEach(function(name) {
document.addEventListener(name, resetTimer, true);
});
DOM事件列表:
请记住根据您的需要使用窗口
,或文档
。在这里您可以看到它们之间的区别:
使用@frank conijn和@daxchen improve:
窗口更新代码。如果滚动在可滚动元素内,onscroll
将不会触发,因为滚动事件不会冒泡。在窗口中。addEventListener('scroll',resetTimer,true)
,第三个参数告诉侦听器在捕获阶段而不是冒泡阶段捕获事件。我创建了一个小型库,可以执行以下操作:
说明:
用于在浏览器中报告用户活动的微型JavaScript库
(离开、空闲、不看网页、在不同的选项卡中等)。这与任何
其他JavaScript库,如jQuery
Visual Studio用户可以通过以下方式从NuGet获得它:
Install-Package Idle.js
我已经测试了此代码工作文件:
var timeout = null;
var timee = '4000'; // default time for session time out.
$(document).bind('click keyup mousemove', function(event) {
if (timeout !== null) {
clearTimeout(timeout);
}
timeout = setTimeout(function() {
timeout = null;
console.log('Document Idle since '+timee+' ms');
alert("idle window");
}, timee);
});
你可以用和做得更优雅- 改进: .
除了活动检测方面的改进,以及从
document
更改为window
,此脚本实际上调用了函数,而不是让它闲置
它不会直接捕获零CPU使用率,但这是不可能的,因为执行函数会导致CPU使用率。用户不活动最终会导致零CPU使用率,因此它会间接捕获零CPU使用率。所有这些解决方案的问题,尽管正确,但考虑到会话超时v,它们是不切实际的aluable set,使用PHP、.NET或Application.cfc文件供开发人员使用 上述解决方案设置的时间需要与服务器端会话超时同步。如果两者不同步,您可能会遇到问题,这只会让您的用户感到沮丧和困惑 例如,服务器端会话超时可能设置为60分钟,但用户可能认为他/她是安全的,因为JavaScript空闲时间捕获增加了用户可以在单个页面上花费的总时间。用户可能花时间填写了一个长表单,然后去提交。会话超时可能会触发在处理表单提交之前输入 我倾向于给我的用户180分钟,然后使用JavaScript自动注销用户
window.addEventListener('load', resetTimer, true);
var events = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart'];
events.forEach(function(name) {
document.addEventListener(name, resetTimer, true);
});
Install-Package Idle.js
var timeout = null;
var timee = '4000'; // default time for session time out.
$(document).bind('click keyup mousemove', function(event) {
if (timeout !== null) {
clearTimeout(timeout);
}
timeout = setTimeout(function() {
timeout = null;
console.log('Document Idle since '+timee+' ms');
alert("idle window");
}, timee);
});
$('body').on("click mousemove keyup", _.debounce(function(){
// do preload here
}, 1200000)) // 20 minutes debounce
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.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();
idleTimer = null;
idleState = false;
idleWait = 2000;
(function ($) {
$(document).ready(function () {
$('*').bind('mousemove keydown scroll', function () {
clearTimeout(idleTimer);
if (idleState == true) {
// Reactivated event
$("body").append("<p>Welcome Back.</p>");
}
idleState = false;
idleTimer = setTimeout(function () {
// Idle Event
$("body").append("<p>You've been idle for " + idleWait/1000 + " seconds.</p>");
idleState = true; }, idleWait);
});
$("body").trigger("mousemove");
});
}) (jQuery)
<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>
function setIdleTimeout(millis, onIdle, onUnidle) {
var timeout = 0;
startTimer();
function startTimer() {
timeout = setTimeout(onExpires, millis);
document.addEventListener("mousemove", onActivity);
document.addEventListener("keydown", onActivity);
}
function onExpires() {
timeout = 0;
onIdle();
}
function onActivity() {
if (timeout) clearTimeout(timeout);
else onUnidle();
//since the mouse is moving, we turn off our event hooks for 1 second
document.removeEventListener("mousemove", onActivity);
document.removeEventListener("keydown", onActivity);
setTimeout(startTimer, 1000);
}
}
$(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]
});
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";
}
}
/* 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;
}]);
myApp.run(['idleChecker',function(idleChecker){
idleChecker.init();
}]);
(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);
}());
$(document).idle({
onIdle: function(){
alert('You did nothing for 5 seconds');
},
idle: 5000
})
var idleTime;
$(document).ready(function () {
reloadPage();
$('html').bind('mousemove click mouseup mousedown keydown keypress keyup submit change mouseenter scroll resize dblclick', function () {
clearTimeout(idleTime);
reloadPage();
});
});
function reloadPage() {
clearTimeout(idleTime);
idleTime = setTimeout(function () {
location.reload();
}, 3000);
}
(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);
});
}());
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);
},
sessionExpiration(idleMinutes, warningMinutes, logoutUrl);
const timer = new IdleTimer(() => alert('idle for 1 minute'), 1000 * 60 * 1);
timer.activate();
const derivedLogout = createDerivedLogout(30);
derivedLogout(); // It could happen that the user is too idle)
window.addEventListener('click', derivedLogout, false);
window.addEventListener('mousemove', derivedLogout, false);
window.addEventListener('keyup', derivedLogout, false);
function createDerivedLogout (sessionTimeoutInMinutes) {
return _.debounce( () => {
window.location = this.logoutUrl;
}, sessionTimeoutInMinutes * 60 * 1000 )
}
var idle = false;
document.querySelector('body').addEventListener('mousemove', function(e) {
if(idle!=false)
idle = false;
});
var idleI = setInterval(function()
{
if(idle == 'inactive')
{
return;
}
if(idle == true)
{
idleFunction();
idle = 'inactive';
return;
}
idle = true;
}, 30000); // half the expected time. Idle will trigger after 60 s in this case.
function idleFuntion()
{
console.log('user is idle');
}
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(() => {...}, {
timeout: 2000
});
class _Scheduler {
timeoutIDs;
constructor() {
this.timeoutIDs = new Map();
}
addCallback = (callback, timeLapseMS, autoRemove) => {
if (!this.timeoutIDs.has(timeLapseMS + callback)) {
let timeoutID = setTimeout(callback, timeLapseMS);
this.timeoutIDs.set(timeLapseMS + callback, timeoutID);
}
if (autoRemove !== false) {
setTimeout(
this.removeIdleTimeCallback, // Remove
10000 + timeLapseMS, // 10 secs after
callback, // the callback
timeLapseMS, // is invoked.
);
}
};
removeCallback = (callback, timeLapseMS) => {
let timeoutID = this.timeoutIDs.get(timeLapseMS + callback);
if (timeoutID) {
clearTimeout(timeoutID);
this.timeoutIDs.delete(timeLapseMS + callback);
}
};
}
class _IdleTimeScheduler extends _Scheduler {
events = [
'load',
'mousedown',
'mousemove',
'keydown',
'keyup',
'input',
'scroll',
'touchstart',
'touchend',
'touchcancel',
'touchmove',
];
callbacks;
constructor() {
super();
this.events.forEach(name => {
document.addEventListener(name, this.resetTimer, true);
});
this.callbacks = new Map();
}
addIdleTimeCallback = (callback, timeLapseMS) => {
this.addCallback(callback, timeLapseMS, false);
let callbacksArr = this.callbacks.get(timeLapseMS);
if (!callbacksArr) {
this.callbacks.set(timeLapseMS, [callback]);
} else {
if (!callbacksArr.includes(callback)) {
callbacksArr.push(callback);
}
}
};
removeIdleTimeCallback = (callback, timeLapseMS) => {
this.removeCallback(callback, timeLapseMS);
let callbacksArr = this.callbacks.get(timeLapseMS);
if (callbacksArr) {
let index = callbacksArr.indexOf(callback);
if (index !== -1) {
callbacksArr.splice(index, 1);
}
}
};
resetTimer = () => {
for (let [timeLapseMS, callbacksArr] of this.callbacks) {
callbacksArr.forEach(callback => {
// Clear the previous IDs
let timeoutID = this.timeoutIDs.get(timeLapseMS + callback);
clearTimeout(timeoutID);
// Create new timeout IDs.
timeoutID = setTimeout(callback, timeLapseMS);
this.timeoutIDs.set(timeLapseMS + callback, timeoutID);
});
}
};
}
export const Scheduler = new _Scheduler();
export const IdleTimeScheduler = new _IdleTimeScheduler();