当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《如何优雅地检测JavaScript中的空闲时间?》经验,为你挑选了15个好方法。

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

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



1> freddoo..:

这是一个使用JQuery处理mousemove和keypress事件的简单脚本.如果时间到期,则页面重新加载.

   


在$(document).ready(function()体之后你缺少一个分号.另外,在调用setInterval时,它不能使用函数名称周围的引号,你不需要括号后面的括号.只是:setInterval(timerIncrement,60000)
@Jesse:你的建议都很好,这就是代码应该如何.但我只想指出即使没有这些更改,代码也完全正常运行.表达式语句末尾的分号是可选的,您实际上可以将字符串传递给`setInterval`,然后将其作为JavaScript进行求值.
这对用户的系统来说不重吗?比方说,一个用户在浏览器上使用相当旧的浏览器,在一个javascript应用程序中运行半天,并且每次用户移动他的鼠标时它都在处理这些功能......我想知道这是否赢了" t影响用户的体验......
您可以简单地使用`idleTime ++;`而不是`idleTime = idleTime + 1;`
@PietBinnenbocht另外,如果你开始优化这样的事情,你也可以改变每个带有像'mousemove keydown click'这样的字符串的函数来使用位标志(`Event.MOUSEMOVE | Event.KEYDOWN | Event.CLICK`),因为它们比字符串操作更快.但你真的**想要这样做吗?
我认为最好使用`keydown`事件(因为它会在keypress之前发生)+添加`click`事件.你可以用一种方法加入事件:`$(this).on('mousemove keydown click',function(){idleTime = 0;});`
@Sander关于性能 - 将"0"分配给"idleTime"几乎没有成本.嘿,我甚至为你做了jsperf测试:http://jsperf.com/setting-values这是~660 MOps /秒,你真的想优化吗?不要过早优化,在遇到瓶颈时再进行优化.我可以向你保证,它不会是`idleTime = 0`.

2> equiman..:

不使用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
    }
};

致谢: http ://forums.devshed.com/javascript-development-115/alert-time-inactivity-click-logout-501444.html

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

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

或者使用数组注册所需的事件

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

DOM事件列表:http://www.w3schools.com/jsref/dom_obj_event.asp

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


我更喜欢简单的javascript方法.
当计时器本身可以是(高精度)计数器时,确定重置计时器是一种更直接/直观和准确的方法,而不是超时执行它,只保留另一个事物的整数计数.
有一个标志var notidle会更好;仅在事件上将该标志设置为true。然后在resetTimer函数中测试notidle标志是否为true,是否重置了定时器或调用注销。这将消除不断重置计时器的复杂性开销。
@mpsbhat只需添加一个console.log或一个警告,看看是否有效.或者注册这个事件:`document.onload = function(){inactivityTime(); }; document.onmousedown = function(){inactivityTime(); }; document.onkeypress = function(){inactivityTime(); }; document.ontouchstart = function(){inactivityTime(); };`
是的......工作.https://jsfiddle.net/mpsbhat/6b6mja5t/1​​/.谢谢@equiman
我不想覆盖任何现有的事件处理程序,所以我使用了:`window.addEventListener(“ load”,resetTimer,true); [“ mousedown”,“ mousemove”,“ keypress”,“ scroll”,“ touchstart” ] .forEach(function(name){document.addEventListener(name,resetTimer,true);});`受@JackTheKnife的回答启发

3> Frank Conijn..:

改进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使用率.


只是想指出,如果在可滚动元素内滚动,则“ window.onscroll”将不会触发,因为滚动事件不会冒泡。使用`window.addEventListener('scroll',resetTimer,true)`,第三个参数告诉侦听器在`capture`阶段而不是`bubble`阶段(IE> 8)捕获事件,[查看此答案](https: //stackoverflow.com/a/32954565/4997172)
是的,我要说的是使用addEventListener而不是onscroll。

4> Shawn Mclean..:

我创建了一个小型库,它在一年前完成了这项工作:

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

描述:

用于在浏览器中报告用户活动的小型JavaScript库(离开,空闲,不看网页,在不同的选项卡中等).它独立于任何其他javascript库,如jquery.

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



5> Peter J..:

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

})


此解决方案不考虑键盘事件.
永远不要传递`setInterval`字符串!只需将函数作为变量!

6> Tracker1..:

类似于上面的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)))



7> Kruttik..:

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

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



8> johnnyRose..:

我的回答是受到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分钟后重新加载当前页面.

这利用普通的vanilla JavaScript和一个立即调用的函数表达式来以一种干净和自包含的方式处理空闲超时.



9> DDan..:

我知道这是一个相对古老的问题,但我遇到了同样的问题,我发现了一个非常好的解决方案.

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

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

参见JsFiddle演示.

(仅供参考:请参阅此内容以了解后端事件跟踪引导浏览器负载)



10> Hai Phan..:

以前的所有答案都有一个始终有效的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/



11> tvanfosson..:

您可以通过检测表单主体上的鼠标移动并使用最后一个移动时间更新全局变量来解决某些问题.然后,您需要运行间隔计时器,定期检查最后一次运动时间,如果检测到最后一次鼠标移动已经足够长,则会执行一些操作.



12> rajsite..:

如果您定位支持的浏览器(自2018年12月起为Chrome或Firefox),您可以试用requestIdleCallback并为不支持的浏览器添加requestIdleCallback填充程序.



13> SPidey..:
 

我认为这个jquery代码是完美的,虽然从上面的答案复制和修改!donot忘了在你的文件中包含jquery库!



14> 小智..:

试试这个完美的工作..

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



15> Capi Etherie..:

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

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

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

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

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

推荐阅读
刘美娥94662
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有