如何优雅地检测JavaScript中的空闲时间?


477

是否可以在JavaScript中检测“ 空闲 ”时间?
我的主要用例可能是预取或预加载内容。

空闲时间:用户不活动或没有使用CPU的时间


7
您如何定义空闲时间?
Itay Moav -Malimovka,2009年


74
这里几乎有50%的答案都将jQuery用于纯Javascript这样简单的任务。这是愚蠢的,特别是当OP需要Java脚本时。要求草莓冰淇淋,但改为改用半独立式谷仓。
TheCarver '16

4
多数民众赞成在您的StackOverflow
Robertmain

5
@TheCarver-必须为如此简单的东西安装一个jQuery库确实是荒谬的,它延长了渲染时间并提高了能耗。人们应该进一步向下滚动。在香草Javascript中也有几乎复制粘贴的解决方案。
弗兰克·康尼

Answers:


437

这是一个使用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>   

16
您在$(document).ready(function()主体之后缺少分号,而且在对setInterval的调用中,该函数不能使用函数名周围的引号,并且不需要在其后加上括号。公正:setInterval(timerIncrement,60000)
Jesse Roper

9
@Jesse:您的建议都很好,代码应该是这样的。但我只想指出,即使不进行这些更改,代码也可以完全起作用。expression语句末尾的分号是可选的,实际上您可以将字符串传递给setInterval,然后将其评估为JavaScript。
Felix Kling 2013年

6
你可以简单地使用idleTime++;,而不是idleTime = idleTime + 1;
麦克CAUSER

7
这对用户的系统是否繁重?假设某个用户在不那么笨重的PC上使用相当旧的浏览器,并且在javascript应用程序中工作了半天,并且每次用户移动鼠标时都在处理这些功能……我想知道这是否会成功?会影响用户的体验...
Sander 2014年

5
@PietBinnenbocht另外,如果您开始优化诸如此类的操作,则最好更改每个'mousemove keydown click'使用字符串的函数,例如使用位标志(Event.MOUSEMOVE | Event.KEYDOWN | Event.CLICK),因为它们比字符串操作快得多。但是您真的要这样做吗?
Killah 2014年

361

如果不使用jQuery,则仅使用普通JavaScript:

var inactivityTime = function () {
    var time;
    window.onload = resetTimer;
    // DOM Events
    document.onmousemove = resetTimer;
    document.onkeypress = 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
    }
};

然后在需要的地方初始化函数(例如:onPageLoad)。

window.onload = function() {
  inactivityTime(); 
}

如果需要,可以添加更多的DOM事件。最常用的是:

document.onload = resetTimer;
document.onmousemove = resetTimer;
document.onmousedown = resetTimer; // touchscreen presses
document.ontouchstart = resetTimer;
document.onclick = resetTimer;     // touchpad clicks
document.onkeypress = resetTimer;
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事件列表:http : //www.w3schools.com/jsref/dom_obj_event.asp

记住使用window,或document根据您的需要。在这里,您可以看到它们之间的区别:Java窗口,屏幕和文档之间的区别是什么?

使用@ frank-conijn和@daxchen进行更新的代码得到改进:window.onscroll如果滚动位于可滚动元素内部,则不会触发,因为滚动事件不会冒泡。window.addEventListener('scroll', resetTimer, true),第三个参数告诉侦听器在捕获阶段而不是冒泡阶段捕获事件。


58
我更喜欢纯JavaScript方法。
Manatax

4
肯定的是,重置计时器是一种比计时超时更直接/直观和准确的方法,仅当计时器本身可以用作(高精度)计数器时,才保留另一件事的整数计数。
Josh Sutterfield '16

2
@mpsbhat只需添加console.log或警报,看看是否可行。或注册此事件:document.onload = function () { inactivityTime(); }; document.onmousedown = function () { inactivityTime(); }; document.onkeypress = function () { inactivityTime(); }; document.ontouchstart = function () { inactivityTime(); };
equiman

2
是的...工作。jsfiddle.net/mpsbhat/6b6mja5t/1。感谢@equiman
mpsbhat

6
有一个标志var notidle会更好;仅在事件上将该标志设置为true。然后在resetTimer函数中测试notidle标志是否为true,是否重置了定时器或调用注销。这将消除不断重置计时器的复杂性开销。
MartinWebb '16

75

改善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.onclick = resetTimer;      // catches touchpad clicks as well
    window.onkeypress = 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();


除了在活动检测方面的改进以及从document到的更改之外window,该脚本实际上调用了该函数,而不是让其闲置。

它不会直接捕获零CPU使用率,但这是不可能的,因为执行函数会导致CPU使用率。用户的不活动最终导致CPU使用率为零,因此间接地确实导致CPU使用率为零。


3
只是想指出,window.onscroll如果滚动位于可滚动元素内部,则不会触发,因为滚动事件不会冒泡。使用window.addEventListener('scroll', resetTimer, true),第三个参数告诉侦听器在capture阶段而不是bubble阶段(IE> 8)捕获事件,请参见此答案
DaxChen

@DaxChen-是否document.onscroll有相同的问题,如果滚动位于可滚动子项中,则不会触发?
Frank Conijn '18年

2
是的,我的意思是要使用addEventListener而不是onscroll
DaxChen

@DaxChen-好的,我想知道您是否是要解决这个问题,但是现在很清楚。我相应地编辑了答案。感谢您的评论。
Frank Conijn '18年

我将使用此重要信息更新答案,以帮助其他人复制并粘贴我的错误。感谢@DaxChen和Frank
equiman

33

我一年前创建了一个小库:

https://github.com/shawnmclean/Idle.js

描述:

小型的javascript库,用于报告用户在浏览器中的活动(离开,空闲,不查看网页,在其他标签中等)。与其他任何JavaScript库(例如jquery)无关。

Visual Studio用户可以通过以下方式从NuGet中获取它: PM> Install-Package Idle.js


32

这是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.
   }

})

9
此解决方案不考虑键盘事件。
Daniel Silveira 2010年

7
永远不要传递setInterval字符串!只要给一个函数作为变量!
艾瑞克(Eric)

1
这实际上不起作用,因为传递字符串来setInterval()评估全局范围内的表达式,因此无法找到timerIncrement().ready处理函数内部的函数。这是永远不要将字符串传递给的另一个原因setInterval()。只要传递一个实际的函数引用,您就不会遇到这个问题,因为它们是在当前范围内进行评估的。
jfriend00 2013年

谢谢,我不知道永远不要将字符串传递给setInterval。更新了我的答案。
彼得J

24

类似于上面的Iconic解决方案(带有jQuery自定义事件)...

// use jquery-idle-detect.js script below
$(window).on('idle:start', function(){
  //start your prefetch etc here...
});

$(window).on('idle:stop', function(){
  //stop your prefetch etc here...
});

//jquery-idle-detect.js
(function($,$w){
  // expose configuration option
  // idle is triggered when no events for 2 seconds
  $.idleTimeout = 2000;

  // currently in idle state
  var idle = false;

  // handle to idle timer for detection
  var idleTimer = null;

  //start idle timer and bind events on load (not dom-ready)
  $w.on('load', function(){
    startIdleTimer();
    $w.on('focus resize mousemove keyup', startIdleTimer)
      .on('blur',idleStart) //force idle when in a different tab/window
      ;
  ]);

  function startIdleTimer() {
    clearTimeout(idleTimer); //clear prior timer

    if (idle) $w.trigger('idle:stop'); //if idle, send stop event
    idle = false; //not idle

    var timeout = ~~$.idleTimeout; // option to integer
    if (timeout <= 100) timeout = 100; // min 100ms
    if (timeout > 300000) timeout = 300000; // max 5 minutes

    idleTimer = setTimeout(idleStart, timeout); //new timer
  }

  function idleStart() {
    if (!idle) $w.trigger('idle:start');
    idle = true;
  }

}(window.jQuery, window.jQuery(window)))

20

您可以使用下划线jquery更优雅地做到这一点-

$('body').on("click mousemove keyup", _.debounce(function(){
    // do preload here
}, 1200000)) // 20 minutes debounce

16

我的回答受到了vijay的回答的启发,但是是一个简短,更笼统的解决方案,我认为我会与可能会帮助的任何人分享。

(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和立即调用的函数表达式以干净且自成体系的方式处理空闲超时。


document.onclick使用我自动编写的.trigger('click')考虑javascript函数。因此,这实际上不是用户交互,但是在这种情况下,它将重置idleCounter
Carmela

@Carmela:我不确定为什么我只是看到这个;我一定错过了。谢谢,我删除了onclick作业,因为除此作业外可能没有其他必要onmousemove,但显然,以编程方式触发的所有这些事件都将继续重置idleCounter。我不确定您为什么要模拟用户交互而不仅仅是调用一个函数,但是如果出于某种原因您需要这样做,那么此答案显然对您不起作用,其他大多数答案我也不会我看了这个问题。
johnnyRose

15

我知道这是一个相对较旧的问题,但是我遇到了同样的问题,并且找到了一个很好的解决方案。

我使用过:jquery.idle ,我只需要这样做:

$(document).idle({
  onIdle: function(){
    alert('You did nothing for 5 seconds');
  },
  idle: 5000
})

参见JsFiddle演示

(仅供参考:后端事件跟踪Leads browserload参见此内容


我如何停止该功能,他们说一个事件为idle:stop,但老实说我不知道​​如何使用此功能。我希望如果我移至下一页(基于ajax,因此仅更新了HTML页面的一部分),那么空闲功能将停止。你知道如何做到这一点吗?
Mubasher

在这里,它说:“怠速:停”:停止和删除用户跟踪
DDan

我已经读过,但不知道如何使用,您能帮我吗?
Mubasher

如果只希望触发一次,则可以将keepTracking选项设置为false。如果您想重置,可以尝试重新初始化。这是一个仅触发一次的修改示例:jsfiddle.net/f238hchm/12
DDan 2016年

不,我不触发一次,keepTracking应该为true,但是在导航至其他页面时,我想停止此操作
Mubasher

15

先前的所有答案都有一个始终处于活动状态的mousemove处理程序。如果处理程序是jQuery,则jQuery所执行的其他处理可以加起来。特别是如果用户使用游戏鼠标,则每秒最多可能发生500个事件。

此解决方案避免处理每个mousemove事件。这样会导致较小的时序误差,但是您可以根据需要进行调整。

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);
    }
}

http://jsfiddle.net/jndxq51o/


1
将其放置在页面上是否会自动工作,还是需要放在$(document).ready()包装器中?谢谢!另外,计时器到期时执行动作的部分在哪里?
Oranges13年

1
您甚至可以在文档准备好之前随时调用此方法。您传递了一个函数“回调”,它将在计时器到期时被调用。
Sarsaparilla

1
$(startTimer)相当于$(document).ready(startTimer),确保DOM你钩鼠标移动和按键事件之前准备就绪。
Sarsaparilla 2015年

1
+1这就是我的工作-鼠标移动处理程序会导致速度变慢并缩短电池寿命,因此,如果您可以承受较小的计时错误,则仅定期打开它是一个好主意。我通常将空闲时间检测用于自动会话到期警告(例如“您还在吗?”),因此在用户进入“空闲”之前,我往往要花几分钟的时间,在这种情况下,很小的计时错误是完全不相关的。
山羊

1
最好使用“ keydown”而不是“ keypress”,因为“ keypress”事件未检测到箭头键。因此,如果用户使用箭头键浏览该页面,则该页面无论如何都将变为“空闲”。
aFerrer

13

您可能会通过检测鼠标在表单主体上的移动并使用最后一次移动时间更新全局变量来一起破解某些东西。然后,您需要运行一个间隔计时器,该计时器会定期检查上一次移动时间,并且如果自检测到上一次鼠标移动以来时间足够长,则应执行一些操作。


重要的是要注意,脚本将只能检测页面正文上的运动,而不能检测所有用户输入。我认为没有办法从javascript获取CPU或进程信息。
Dave Swersky 09年

1
我采取了在jQuery中实现您的想法的自由。
Peter J

9

我写了一个小的ES6类来检测活动,否则将在空闲超时时触发事件。它涵盖了键盘,鼠标和触摸,可以被激活和停用,并且具有非常精简的API:

const timer = new IdleTimer(() => alert('idle for 1 minute'), 1000 * 60 * 1);
timer.activate();

依赖于jQuery的,虽然你可能需要通过通天运行它支持旧版浏览器。

https://gist.github.com/4547ef5718fd2d31e5cdcafef0208096

一旦收到一些反馈,我可能会将其作为npm软件包发布。



6

试试此代码,它可以完美地工作。

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";
    }
}

加1表示是香草js
frostymarvelous 2015年

5
<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库!


4

所有这些解决方案的问题,尽管是正确的,但考虑到会话超时有价值的设置(使用PHP,.NET或Coldfusion开发人员的Application.cfc文件)时,它们都不切实际。上述解决方案设置的时间需要与服务器端会话超时同步。如果两者不同步,则可能会遇到麻烦,只会使用户感到沮丧和困惑。例如,服务器端会话超时可能设置为60分钟,但用户可能认为他/她是安全的,因为JavaScript空闲时间捕获增加了用户可以花在单个页面上的总时间。用户可能已经花了很长时间填写较长的表格,然后去提交。会话超时可能在处理表单提交之前开始。我倾向于给用户180分钟,然后使用JavaScript自动将用户注销。本质上,使用上面的一些代码创建一个简单的计时器,但没有捕获鼠标事件部分。这样,我的客户端和服务器端时间可以完美同步。如果您在用户界面中向用户显示时间,则不会造成混乱,因为这会减少时间。每次在CMS中访问新页面时,服务器端会话和JavaScript计时器都会重置。简单而优雅。如果用户在一个页面上停留超过180分钟,那么我认为该页面首先存在问题。随着它减少。每次在CMS中访问新页面时,服务器端会话和JavaScript计时器都会重置。简单而优雅。如果用户在一个页面上停留超过180分钟,那么我认为该页面首先存在问题。随着它减少。每次在CMS中访问新页面时,服务器端会话和JavaScript计时器都会重置。简单而优雅。如果用户在一个页面上停留超过180分钟,那么我认为该页面首先存在问题。


1
是的,这就是为什么我只有在摆脱服务器端会话并从html文件加载所有内容之后才这样做。
Dan Parker

4

具有正确设置重置时间和绑定的纯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);
  });

}());

4

(部分受本主题前面的Equiman良好的核心逻辑启发。)

sessionExpiration.js


sessionExpiration.js轻巧但有效且可自定义。实施后,只需一行即可使用:

sessionExpiration(idleMinutes, warningMinutes, logoutUrl);
  • 影响浏览器的所有标签,而不仅仅是一个。
  • 纯JavaScript编写,没有依赖关系。完全是客户端。
  • (如果需要的话。)具有警告标语倒计时时钟,可通过用户交互取消。
  • 只需包含sessionExpiration.js,然后调用函数,其参数为[1]直到用户注销为止的空闲分钟数(在所有选项卡上),[2]直到显示警告和倒计时的空闲分钟数,以及[3]注销网址。
  • 将CSS放入样式表中。如果愿意,可以自定义它。(或者,如果不需要,请跳过并删除横幅。)
  • 但是,如果您确实想要警告横幅,则必须在页面上放置一个ID为sessExpirDiv的空div (建议将其放在页脚中)
  • 现在,如果所有标签在给定的时间内都处于非活动状态,则用户将自动注销。
  • 可选:您可以向函数提供第四个参数(URL serverRefresh),以便在与页面交互时也刷新服务器端会话计时器。

如果您不更改CSS,这就是实际操作的一个示例。

demo_image


3

我写了一个简单的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]
});

该脚本将侦听鼠标,键盘,触摸和其他自定义事件的不活动(空闲),并触发全局“活动”和“不活动”事件。

希望这可以帮助 :)


是否真的需要延迟,从自定义事件处理程序触发自定义事件还不够吗?
Hibou57年

2

只是一些想法,一两个探索的途径。

是否可以让函数每10秒运行一次,并检查“计数器”变量?如果可以的话,您可以将鼠标悬停在页面上,可以吗?如果是这样,请使用mouseover事件重置“计数器”变量。如果调用了函数,并且计数器在您预定的范围之上,请执行操作。

再说一遍,只是一些想法...希望能有所帮助。


2

我已经测试了此代码工作文件:

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);
    });

2

这是我找到的最佳解决方案:http : //css-tricks.com/snippets/jquery/fire-event-when-user-is-idle/

这是JS:

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)

2

您可以使用以下提到的解决方案

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);
}

2

我使用这种方法,因为您不需要在事件触发时不断重置时间,而是只记录时间,这会生成空闲开始点。

           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);    
        },

1

您可能会使用列出的mousemove技巧检测到网页上的不活动状态,但这并不能告诉您该用户不在另一个窗口或选项卡中的另一个页面上,或者该用户不在Word或Photoshop中,或者在WOW和只是目前不在看您的页面。通常,我只是做预取并依靠客户端的多任务处理。如果您确实需要此功能,则可以使用Windows中的activex控件来执行某些操作,但这充其量是丑陋的。


1

这是用于在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;
}]);

请记住,此空闲检查程序将在所有路径上运行,因此应在.run()有角度应用程序加载时对其进行初始化。然后,您可以idleChecker.secondsIdle在每条路线内使用。

myApp.run(['idleChecker',function(idleChecker){
    idleChecker.init();
}]);

1

反跳实际上是个好主意!此处为jQuery免费项目版本:

const derivedLogout = createDerivedLogout(30);
derivedLogout(); // it could happen that user 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 ) 
}

1

尽可能简单地检测鼠标何时移动:

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 60s in this case.

function idleFuntion()
{
   console.log('user is idle');
}

0

好吧,您可以将click或mousemove事件附加到文档主体,以重置计时器。有一个您可以按时间间隔调用的函数,该函数可以检查计时器是否超过指定的时间(例如1000毫秒),然后开始预加载。


0

Javascript无法告诉CPU使用情况。这将破坏沙箱中运行的javascript。

除此之外,挂接页面的onmouseover和onkeydown事件可能会起作用。

您还可以在onload事件中设置使用setTimeout来安排延迟后调用的函数。

// Call aFunction after 1 second
window.setTimeout(aFunction, 1000);

3
我不知道为什么这么多反对这个答案。据我所知,它确实回答了所提出的问题,并且实际上是正确的。只是没有继续推出详尽的代码示例。
Ifedi Okonkwo 2015年

1
现在,可以调用javascript函数时,“有空闲时间在一帧的结束,或者当用户处于非活动状态。” developers.google.com/web/updates/2015/08/...
马克斯

setTimeout 0通过计算FILO之间的时间来平均计算缓冲区的满度可能更正确
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.