Як вишукано виявити час простою в JavaScript?


478

Чи можливо виявити " неробочий " час у JavaScript?
Моїм основним випадком використання, мабуть, було б попереднє завантаження або попереднє завантаження вмісту.

Час очікування: Період бездіяльності користувача або без використання ЦП


7
Як визначити ІДЕЙНИЙ ЧАС?
Itay Moav -Malimovka


74
Майже 50% відповідей тут використовували jQuery для такого простого завдання для чистого Javascript. Це не давно, тим більше, що ОП хотів Javascript. Попросіть полуничне морозиво, але замість цього отримайте напіврозділене сарай.
TheCarver

4
thats StackOverflow для вас
robertmain

5
@TheCarver - Потрібно встановити бібліотеку jQuery для чогось такого простого, насправді смішно, і це подовжує час візуалізації та збільшує споживання енергії. Люди повинні прокрутити вниз трохи далі. У ванільному Javascript також є рішення з майже копіювальною вставкою.
Френк Конійн

Відповіді:


437

Ось простий скрипт з використанням 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>   

16
Вам не вистачає крапки з комою після тіла $ (document) .ready (function (). Також у виклику до setInterval він не працюватиме з лапками навколо назви функції, і вам не потрібні дужки після нього. Просто: setInterval (timerIncrement, 60000)
Джессі Ропер

9
@Jesse: Ваші пропозиції хороші, ось яким повинен бути код. Але я просто хотів зазначити, що навіть без цих змін код є повністю функціональним. Точки з комою в кінці виразу виразу необов’язкові, і ви можете фактично передати рядок до setInterval, який потім оцінюється як JavaScript.
Фелікс Клінг

6
Ви можете просто використовувати idleTime++;замість цьогоidleTime = idleTime + 1;
Майк Каузер

7
Це не важка система користувача? Скажімо, користувач із досить старим браузером на не такому важкому ПК працює півдня на додатку javascript, і він обробляє ці функції щоразу, коли користувач рухає мишкою ... Цікаво, чи це виграло ' t впливає на досвід користувача ...
Сандер

5
@PietBinnenbocht Крім того, якщо ви почнете оптимізувати такі речі, ви можете також змінити кожну функцію, яка займає рядки, як 'mousemove keydown click'використання бітових прапорів ( Event.MOUSEMOVE | Event.KEYDOWN | Event.CLICK), оскільки вони швидше, ніж рядкові операції. Але чи справді ти хочеш це зробити?
Кілла

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відповідно до своїх потреб. Тут ви можете побачити відмінності між ними: Яка різниця між вікном, екраном та документом у Javascript?

Код, оновлений на @ frank-conijn та @daxchen, покращиться: window.onscrollне запуститься, якщо прокрутка знаходиться всередині прокручуваного елемента, оскільки події прокрутки не спливають. window.addEventListener('scroll', resetTimer, true), третій аргумент говорить слухачеві вловлювати подію під час фази захоплення замість фази бульбашки.


58
Мені подобається звичайний підхід до JavaScript набагато краще.
Манатакс

4
безумовно, скидання таймера є більш прямим / інтуїтивно зрозумілим та точним підходом, ніж тимчасовий тайм-аут зробити свою справу, лише щоб зберегти цілий підрахунок іншої речі, коли сам таймер може БУТИ (високоточний) лічильник.
Джош Саттерфілд

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
Було б набагато краще мати прапор змінного прапора; встановіть цей прапор = вірно лише для подій. Потім у тесті функції resetTimer перевіряється, чи прапор notidle є істинним, якщо він скидається таймером їх, або виходите з виходу. Це призведе до усунення складних витрат на постійне скидання таймера.
MartinWebb

75

Покращення відповіді Еквіман:

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, цей сценарій насправді викликає функцію, а не дозволяє їй сидіти в режимі очікування.

Він не вловлює нульове використання процесора безпосередньо, але це неможливо, оскільки виконання функції викликає використання процесора. І бездіяльність користувача врешті-решт призводить до нульового використання процесора, тому опосередковано він зафіксує нульове використання процесора.


3
Просто хотілося вказати, що window.onscrollне буде запускатись, якщо прокрутка знаходиться всередині прокручуваного елемента, оскільки події прокрутки не спливають. Використовуючи window.addEventListener('scroll', resetTimer, true)третій аргумент, що спонукає слухача зловити подію під час captureфази замість bubbleфази (IE> 8), дивіться цю відповідь
DaxChen

@DaxChen - У вас немає document.onscrollтієї самої проблеми, не стріляючи, якщо прокрутка знаходиться в дитячій програмі?
Френк Конійн

2
Так, пункт, про який я говорив, - використовувати addEventListenerзамість цього onscroll.
DaxChen

@DaxChen - Гаразд, мені було цікаво, чи ти це мав на увазі, щоб попрацювати над цим, але зараз зрозуміло. Відповідь я відредагував відповідно. Дякуємо за коментар
Френк Конійн

Я оновлю свою відповідь цією важливою інформацією, щоб засвідчити іншу копію та вставити свою помилку. Дякую @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
Це рішення не враховує події на клавіатурі.
Даніель Сільвейра

7
Ніколи не передайте setIntervalструну! Просто дайте функцію як змінну!
Ерік

1
Насправді це не спрацює, оскільки передаючи рядок для setInterval()оцінки виразу в глобальній області, і, таким чином, він не знайде timerIncrement()функції, яка знаходиться всередині функції вже обробника. Це ще одна причина НІКОЛИ не передавати рядки setInterval(). Просто передайте фактичну посилання на функцію, і ви не матимете цієї проблеми, оскільки вони оцінені в поточній області.
jfriend00

Дякую, я не усвідомлював необхідності НІКОЛИ не передавати рядки в setInterval. Оновлено мою відповідь.
Пітер Дж

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


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 розглядає функції javascript за допомогою .trigger ('click'), які я написав як автоматизований. Тож це насправді не взаємодія з користувачем, але вона скине idleCounter в цьому випадку
Carmela

@Carmela: Я не впевнений, чому я просто бачу це; Я, мабуть, пропустив це. Дякую, я видалив onclickзавдання, оскільки це, мабуть, не потрібно окрім onmousemove, але очевидно, що будь-яка з цих подій, які запускаються програмно, продовжуватиме скидання idleCounter. Я не впевнений, чому б ви імітували взаємодію користувачів замість того, щоб просто викликати функцію, але якщо це потрібно зробити чомусь, ця відповідь, очевидно, не підійде для вас, а також більшість інших відповідей я ' я дивився на це питання.
johnnyRose

15

Я знаю це відносно старе питання, але у мене було те саме питання, і я знайшов досить вдале рішення.

Я використовував: jquery.idle, і мені потрібно було лише зробити:

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

Див. Демонстрацію JsFiddle .

(Тільки для інформації: перегляньте це для відстеження подій в кінцевому підсумку )


Як я можу зупинити цю функцію. Вони заявили про подія в режимі очікування: зупиніться, але я, чесно кажучи, не знаю, як це використовувати. Я хочу, щоб у випадку, якщо я перейшов на наступну сторінку (на базі ajax, тому оновлений лише фрагмент сторінки HTML), тоді функція простою припиняється. Чи знали ви, як цього досягти?
Мубашер

Тут написано: "idle: stop": зупинить і видалить відстеження користувача
DDan

Я вже читав, але не міг зрозуміти, як це використати. Чи можете ви мені допомогти?
Мубашер

Якщо ви хочете, щоб він вистрілив лише один раз, ви можете встановити keepTrackingпараметр на false. Якщо ви хочете скинути, ви можете спробувати повторно реалізувати. Ось модифікований приклад, який запускається лише один раз: jsfiddle.net/f238hchm/12
DDan

Ні, я не запускаю жодного разу, KeepTracking має бути правдою, але на навігації на іншу сторінку я хочу це зупинити
Mubasher

15

Усі попередні відповіді мають завжди активний обробник миші. Якщо обробник 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/


1
Чи буде це автоматично працювати, якщо розміщуватись на сторінці, чи потрібно знаходитись у обгортці $ (document) .ready ()? Дякую! Крім того, де знаходиться частина, яка виконує дію, коли таймер закінчується?
апельсини13,

1
Ви можете зателефонувати цьому будь-коли, навіть до того, як документ буде готовий. Ви передаєте функцію "зворотний виклик", яка буде викликана, коли таймер закінчиться.
Sarsaparilla

1
Цей $(startTimer)еквівалент $(document).ready(startTimer)гарантує, що DOM буде готовий до того, як підключити події миші та натискання клавіш.
Сарсапарілья

1
+1 Це те, що я роблю - оброблювачі миші сприяють млявості та скороченню ресурсу акумулятора, тому лише періодично включати його - чудова ідея, якщо ви можете дозволити собі незначну помилку синхронізації. Зазвичай я використовую функцію виявлення часу простою для автоматичного попередження про закінчення сеансу (наприклад, "Ви все ще там?"), Тому, як правило, у мене є багато хвилин, перш ніж користувач перейде в режим "простою", і в цьому випадку невелика помилка синхронізації абсолютно не має значення.
коза

1
Краще використовувати "клавіш", ніж "натискання клавіші", оскільки клавіші зі стрілками не виявляються подіями "натискання клавіші". Отже, якщо користувач переміщається сторінкою за допомогою клавіш зі стрілками, вона все одно стане бездіяльною.
aFerrer

13

Можливо, ви могли б зламати щось разом, виявивши рух миші на тілі форми та оновивши глобальну змінну з останнім часом руху. Тоді вам знадобиться запустити таймер інтервалу, який періодично перевіряє останній час руху і робить щось, якщо це було достатньо довго з моменту виявлення останнього руху миші.


Важливо зазначити, що скрипт зможе виявити рух лише на тілі сторінки, а не на всіх введеннях користувача. Я не думаю, що існує спосіб отримати інформацію про процесор чи обробку з JavaScript.
Дейв Сверський

1
Я взяв на себе реалізацію вашої ідеї в jQuery.
Пітер Дж

9

Я написав невеликий клас ES6 для виявлення активності та інших випадків пожежі в режимі очікування. Він охоплює клавіатуру, мишу та сенсорний режим , може бути активований та деактивований та має дуже худий API:

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

Це не залежить від jQuery, хоча вам може знадобитися запустити його через Babel для підтримки старих браузерів.

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

Я можу випустити його як пакет npm, як тільки отримаю відгук.


8

Якщо ви орієнтовані на підтримуваний веб-переглядач (Chrome або Firefox станом на грудень 2018 року), ви можете експериментувати з requestIdleCallback і включити прошивку requestIdleCallback для непідтримуваних веб-переглядачів.


А залишити інші браузери в спокої?
Френк Конінь

Обшивка охоплює всі браузери. І це була єдина відповідь! Інші повільні відповіді стосуються миші. Інтерактивність або процесор було сказано лише як приклад. Як виявити холостий процесор за допомогою миші?

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

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 або у файлі Application.cfc для розробників Coldfusion. Час, встановлений вищевказаним рішенням, повинен синхронізуватися з час очікування сеансу на стороні сервера. Якщо вони не синхронізуються, ви можете зіткнутися з проблемами, які просто засмутять і заплутають ваших користувачів. Наприклад, час очікування сеансу на стороні сервера може бути встановлений на 60 хвилин, але користувач може вважати, що він / вона в безпеці, оскільки захоплення в режимі очікування JavaScript збільшило загальну кількість часу, який користувач може провести на одній сторінці. Користувач, можливо, витратив час на заповнення довгої форми, а потім переходить до його надсилання. Час очікування сеансу може розпочатися до того, як буде оброблено подання форми. Я схильний просто давати своїм користувачам 180 хвилин, а потім скористайтеся JavaScript, щоб автоматично вийти з користувача. По суті, використовуючи деякий код вище, щоб створити простий таймер, але без захоплення частини події миші. Таким чином час мого клієнта та серверний час ідеально синхронізуються. Немає плутанини, якщо ви показуєте користувачеві час у своєму інтерфейсі, оскільки він скорочується. Кожен раз, коли доступ до нової сторінки в CMS, сеанс на сервері та таймер JavaScript скидаються. Простий та елегантний. Якщо користувач залишається на одній сторінці більше 180 хвилин, я вважаю, що зі сторінкою щось не так. як зменшує. Кожен раз, коли доступ до нової сторінки в CMS, сеанс на сервері та таймер JavaScript скидаються. Простий та елегантний. Якщо користувач залишається на одній сторінці більше 180 хвилин, я вважаю, що зі сторінкою щось не так. як зменшує. Кожен раз, коли доступ до нової сторінки в CMS, сеанс на сервері та таймер JavaScript скидаються. Простий та елегантний. Якщо користувач залишається на одній сторінці більше 180 хвилин, я вважаю, що зі сторінкою щось не так.


1
Так, саме тому я роблю це лише після позбавлення від сеансів на сервері та завантаження всього з html-файлів.
Ден Паркер

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

(Частково натхненний хорошою логікою Еквімана раніше в цій темі.)

sessionExpiration.js


sessionExpiration.js - це легкий, але ефективний і налаштований. Після впровадження використовуйте лише один ряд:

sessionExpiration(idleMinutes, warningMinutes, logoutUrl);
  • Впливає на всі вкладки браузера, не лише одну.
  • Написаний у чистому JavaScript , без залежностей. Повністю клієнтська сторона.
  • (Якщо так хочеться.) Має банер попередження та годинник зворотного відліку , який скасовується взаємодією користувача.
  • Просто включіть sessionExpiration.js і викликайте функцію, аргументуючи [1] кількість хвилин на холостому ходу (на всіх вкладках) до виходу користувача, [2] кількість хвилин на холостому ходу до появи попередження та зворотного відліку та [3] URL виходу.
  • Помістіть CSS у таблицю стилів. Налаштуйте його, якщо хочете. (Або пропустіть та видаліть банер, якщо ви цього не хочете.)
  • Якщо ви робите хочете , попередження банер , однак, ви повинні поставити порожній DIV з ID sessExpirDiv на сторінці (пропозиція ставить його в виносці) .
  • Тепер користувач автоматично виходитиме з системи, якщо всі вкладки були неактивними протягом зазначеної тривалості.
  • Необов’язково: Ви можете надати четвертий аргумент (URL-серверRefresh) для функції, щоб таймер сеансу на стороні сервера також був оновлений під час взаємодії зі сторінкою.

Це приклад того, як це виглядає в дії, якщо ви не змінюєте 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 секунд і перевіряти змінну "лічильник"? Якщо це можливо, ви можете мати курсор миші для сторінки, чи не так? Якщо так, використовуйте подію миші, щоб скинути змінну "лічильник". Якщо ваша функція викликана, а лічильник вище діапазону, який ви заздалегідь визначите, то виконайте свої дії.

Знову лише кілька думок ... Сподіваюся, це допомагає.


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

Ви, ймовірно, можете виявити бездіяльність на своїй веб-сторінці за допомогою перелічених хитрощів миші, але це не скаже вам, що користувач не перебуває на іншій сторінці в іншому вікні чи вкладці, або що користувач перебуває в Word або Photoshop, або WOW і наразі просто не переглядає вашу сторінку. Як правило, я б просто зробив попередній вибір і покладався на багатозадачність клієнта. Якщо ви насправді потрібна ця функціональність, ви робите щось із керуванням ActiveX у Windows, але це в кращому випадку некрасиво.


1

Ось послуга AngularJS для виконання в Angular.

/* 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

Debounce насправді чудова ідея! Ось версія для безкоштовних проектів 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

Добре, ви можете приєднати подію натискання або переміщення миші до тіла документа, яке скидає таймер. Отримайте функцію, яку ви викликаєте через тимчасові інтервали, яка перевіряє, чи таймер перевищує визначений час (наприклад, 1000 міліс), і розпочніть попереднє завантаження.


0

У Javascript немає способу розповісти про використання процесора. Це призведе до порушення функціонування javascript у пісочниці всередині.

Крім цього, підключення подій onmouseover та onkeydown сторінки, ймовірно, спрацює.

Ви також можете встановити використання setTimeout у події завантаження для планування функції, яку слід викликати після затримки.

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

3
Цікаво, чому так багато відгуків на цю відповідь. Наскільки я бачу, він відповів на поставлене запитання і є фактично правильним. Тільки не продовжували розгортати докладні приклади коду.
Іфдіді Оконкво

1
Тепер функцію javascript можна викликати, коли "в кінці кадру є вільний час або коли користувач неактивний". Developers.google.com/web/updates/2015/08/…
Макс

setTimeout 0, напевно, правильніше підрахувати, наскільки це повний буфер,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.