是否有可能在JavaScript中检测“空闲”时间?

我的主要用例可能是预取或预加载内容。

我将空闲时间定义为用户不活动或没有任何CPU使用的时间段


当前回答

我创建了一个小的库来做这个:

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

描述:

微小的JavaScript库报告用户在浏览器中的活动 (离开,空闲,没有看网页,在不同的标签,等)。这是独立的 其他JavaScript库,如jQuery。

Visual Studio用户可以从NuGet通过:

Install-Package Idle.js

其他回答

类似于Peter J的解决方案(使用jQuery自定义事件)…

// Use the 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 the 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; // Minimum 100 ms
    if (timeout > 300000)
      timeout = 300000; // Maximum 5 minutes

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

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

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

是否有可能每10秒运行一个函数,并检查一个“计数器”变量?如果可能的话,你可以在页面上进行鼠标悬停,不是吗?

如果是,使用鼠标悬停事件重置“counter”变量。如果函数被调用,并且计数器在您预先确定的范围之上,那么执行您的操作。

你肯定想知道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:

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

并在需要的地方初始化函数(例如: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.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事件列表:http://www.w3schools.com/jsref/dom_obj_event.asp

记得根据需要使用窗口或文档。下面你可以看到它们之间的区别:在JavaScript中,窗口、屏幕和文档之间的区别是什么?

代码更新了@frank-conijn和@daxchen改进:window。如果滚动是在可滚动元素内,Onscroll将不会触发,因为滚动事件不会冒泡。在窗口。addEventListener('scroll', resetTimer, true),第三个参数告诉侦听器在捕获阶段而不是冒泡阶段捕获事件。

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

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