Как элегантно определить простой в JavaScript?


479

Можно ли обнаружить « простой » в JavaScript?
Моим основным вариантом использования, вероятно, будет предварительная загрузка или предварительная загрузка контента.

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


7
Как вы определяете время ожидания?
Итай Моав -Малимовка


74
Почти 50% ответов здесь использовали jQuery для такой простой задачи для чистого Javascript. Это за гранью глупости, особенно потому, что ОП хотел Javascript. Попросите клубничное мороженое, но вместо этого получите полуотдельный сарай.
TheCarver

4
вот вам StackOverflow
Робертмайн

5
@TheCarver - Необходимость установить библиотеку jQuery для чего-то такого простого действительно смешно, и это удлиняет время рендеринга и увеличивает потребление энергии. Люди должны прокрутить немного дальше. В ванильном Javascript также есть решение для копирования и вставки.
Фрэнк Конейн

Ответы:


439

Вот простой скрипт, использующий 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 в течение полдня, и он обрабатывает эти функции каждый раз, когда пользователь перемещает свою мышь ... Интересно, выиграло ли это? не влияет на опыт пользователя ...
Сандер

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

362

Без использования 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-подход гораздо лучше.
Manatax

4
Сброс таймера - это более прямой / интуитивно понятный и точный подход, чем тайм-аут, выполняющий свою функцию, только для того, чтобы сохранить счетчик целых чисел, когда сам таймер может быть (высокоточным) счетчиком.
Джош Саттерфилд

2
@mpsbhat просто добавьте console.log или предупреждение, чтобы увидеть, работает ли. Или зарегистрируйте это событие:document.onload = function () { inactivityTime(); }; document.onmousedown = function () { inactivityTime(); }; document.onkeypress = function () { inactivityTime(); }; document.ontouchstart = function () { inactivityTime(); };
Эквиман

2
Да ... Работаю. jsfiddle.net/mpsbhat/6b6mja5t/1 . Спасибо @equiman
mpsbhat

6
Было бы намного лучше иметь флаг var notidle; установите этот флаг = true только для событий. Затем в функции 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 и Фрэнк
Эквиман

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()функцию, которая находится внутри функции обработчика .ready. Это еще одна причина НИКОГДА не передавать строки 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

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

(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. Если вы хотите сбросить настройки, попробуйте выполнить повторную инициализацию. Вот модифицированный пример, который будет запускаться
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 готова , прежде чем подключить MouseMove и события нажатия клавиш.
Sarsaparilla

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

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

(Частично вдохновлен хорошей базовой логикой Equiman ранее в этой теме.)

sessionExpiration.js


sessionExpiration.js является легким, но эффективным и настраиваемым. После внедрения используйте только одну строку:

sessionExpiration(idleMinutes, warningMinutes, logoutUrl);
  • Влияет на все вкладки браузера, а не только на одну.
  • Написано на чистом JavaScript , без каких-либо зависимостей. Полностью клиентская сторона.
  • (При желании.) Имеет предупреждающий баннер и часы обратного отсчета , которые отменяются при взаимодействии с пользователем.
  • Просто включите sessionExpiration.js и вызовите функцию с аргументами [1] количество минут простоя (на всех вкладках), пока пользователь не выйдет из системы, [2] количество минут простоя, пока не отобразятся предупреждение и обратный отсчет, и [3] URL выхода
  • Поместите CSS в вашу таблицу стилей. Настройте его, если хотите. (Или пропустите и удалите баннер, если он вам не нужен.)
  • Однако, если вы хотите получить предупреждение, тогда вы должны разместить пустой div с идентификатором sessExpirDiv на своей странице (рекомендуется поместить его в нижний колонтитул) .
  • Теперь пользователь автоматически выйдет из системы, если все вкладки были неактивны в течение заданного времени.
  • Необязательно: Вы можете предоставить четвертый аргумент (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 для сброса переменной «counter». Если ваша функция вызывается, а счетчик находится выше предопределенного диапазона, выполните свое действие.

Опять же, только некоторые мысли ... Надеюсь, это поможет.


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

Дебад на самом деле отличная идея! Вот версия для бесплатных проектов 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 нет способа сообщить об использовании процессора. Это нарушит работу javascript в песочнице.

Кроме этого, перехват событий onmouseover и onkeydown страницы, вероятно, будет работать.

Вы также можете установить использование setTimeout в событии onload, чтобы запланировать функцию, вызываемую после задержки.

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

3
Интересно, почему столько ответов на этот ответ? Насколько я вижу, он ответил на заданный вопрос, и это действительно правильно. Только не стал выкладывать сложные примеры кода.
Ifedi Okonkwo

1
Теперь можно вызвать функцию яваскрипта , когда «есть свободное время в конце кадра, или когда пользователь неактивен.» Developers.google.com/web/updates/2015/08/...
Макс

setTimeout 0, вероятно, более правильно вычислять в avarage, насколько заполнен буфер за время между FILO
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.