Как элегантно определить простой в JavaScript? - PullRequest
424 голосов
/ 20 марта 2009

Можно ли определить время " простоя " в JavaScript?
Вероятно, мой основной вариант использования - предварительная загрузка или предварительная загрузка содержимого.

Время простоя: Период бездействия пользователя или без использования процессора

Ответы [ 35 ]

408 голосов
/ 27 октября 2010

Вот простой скрипт, использующий JQuery, который обрабатывает события мыши и нажатия клавиш. Если время истекло, страница перезагрузится.

<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>   
273 голосов
/ 12 апреля 2012

Без использования 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
    }
};
/*call the function*/
<script>
    inactivityTime(); 
</script>

Кредиты: http://forums.devshed.com/javascript-development-115/alert-time-inactivity-click-logout-501444.html

Вы можете добавить больше событий DOM, если вам нужно. Наиболее используемые:

document.onload = resetTimer;
document.onmousemove = resetTimer;
document.onmousedown = resetTimer; // touchscreen presses
document.ontouchstart = resetTimer;
document.onclick = resetTimer;     // touchpad clicks
document.onscroll = resetTimer;    // scrolling with arrow keys
document.onkeypress = resetTimer;

Или зарегистрировать нужные события, используя массив

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 в соответствии с вашими потребностями. Здесь вы можете увидеть различия между ними: В чем разница между окном, экраном и документом в Javascript?

66 голосов
/ 28 июля 2014

Улучшение ответа Эквимана:

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, этот скрипт фактически вызывает функцию, а не позволяет ей бездействовать.

Он не улавливает нулевую загрузку ЦП напрямую, но это невозможно, потому что выполнение функции вызывает использование ЦП. А неактивность пользователя в конечном итоге приводит к нулевой загрузке ЦП, поэтому косвенно она отлавливает нулевую загрузку ЦП.

31 голосов
/ 25 апреля 2013

Я создал небольшую библиотеку, которая делает это год назад:

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

Описание:

Крошечная библиотека javascript для сообщения активности пользователя в браузере. (прочь, без дела, не глядя на веб-страницу, в другую вкладку и т. д.). это не зависит от каких-либо другие библиотеки javascript, такие как jquery.

Пользователи Visual Studio могут получить его из NuGet по: PM> Install-Package Idle.js

30 голосов
/ 20 марта 2009

Вот примерная реализация идеи 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.
   }

})
23 голосов
/ 21 марта 2009

Аналогично решению 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)))
18 голосов
/ 26 июня 2014

Вы можете сделать это более элегантно с подчеркиванием и jquery -

$('body').on("click mousemove keyup", _.debounce(function(){
    // do preload here
}, 1200000)) // 20 minutes debounce
15 голосов
/ 29 декабря 2015

Мой ответ был вдохновлен ответом Виджая , но это более короткое, более общее решение, которым я поделился с кем-нибудь, кому оно могло бы помочь.

(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 и незамедлительно вызываемое выражение функции для чистой и автономной обработки таймаутов простоя.

14 голосов
/ 02 марта 2016

Я знаю, что это довольно старый вопрос, но у меня была та же проблема, и я нашел довольно хорошее решение.

Я использовал: jquery.idle а мне осталось только сделать:

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

См. JsFiddle demo .

(только для информации: см. Это для внутреннего отслеживания событий приводит к загрузке браузера )

12 голосов
/ 31 июля 2015

Все предыдущие ответы имеют всегда активный обработчик перемещения мыши. Если обработчиком является jQuery, дополнительная обработка, которую выполняет jQuery, может сложиться. Особенно, если пользователь использует игровую мышь, может происходить до 500 событий в секунду.

Это решение позволяет избежать обработки каждого события мыши. Это приводит к небольшой ошибке синхронизации, но вы можете настроить ее по своему усмотрению.

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/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...