Тайм-аут Javascript, когда никакие действия пользователя за указанное время
Я хочу вызвать функцию js, если на веб-странице нет активности с определенного количества времени. Если есть активность от пользователя, тогда reset таймаут. Я пытался искать, но ничего не мог найти. Я знаком с setTimeout() и clearTimeout() и как они работают. Я ищу, где/как отслеживать активность пользователя. Есть ли какое-либо событие, в котором я могу установить и очистить таймер?
Спасибо.
Изменить # 1:
На этой веб-странице есть одно текстовое поле ввода и одна кнопка. Это обычная чат-страница. Когда я говорю, что нет активности пользователя, я имею в виду, что пользователь ничего не набрал в текстовом поле или не нажал ни одной кнопки в течение определенного времени. И еще одно, что оно предназначено для смартфонов на сенсорной основе.
Изменить # 2:
Спасибо всем за предложения. Я реализовал решение, основанное на нескольких ответах. Поэтому я отдал бы все ответы, которые я нашел полезными, вместо того, чтобы принимать их в качестве ответа.
Ответы
Ответ 1
// Using jQuery (but could use pure JS with cross-browser event handlers):
var idleSeconds = 30;
$(function(){
var idleTimer;
function resetTimer(){
clearTimeout(idleTimer);
idleTimer = setTimeout(whenUserIdle,idleSeconds*1000);
}
$(document.body).bind('mousemove keydown click',resetTimer); //space separated events list that we want to monitor
resetTimer(); // Start the timer when the page loads
});
function whenUserIdle(){
//...
}
Изменить. Не использовать jQuery по какой-либо причине? Здесь некоторый (непроверенный) код, который должен быть очищен от перекрестного браузера (до точки, не работает на IE5 Mac, например;):
attachEvent(window,'load',function(){
var idleSeconds = 30;
var idleTimer;
function resetTimer(){
clearTimeout(idleTimer);
idleTimer = setTimeout(whenUserIdle,idleSeconds*1000);
}
attachEvent(document.body,'mousemove',resetTimer);
attachEvent(document.body,'keydown',resetTimer);
attachEvent(document.body,'click',resetTimer);
resetTimer(); // Start the timer when the page loads
});
function whenUserIdle(){
//...
}
function attachEvent(obj,evt,fnc,useCapture){
if (obj.addEventListener){
obj.addEventListener(evt,fnc,!!useCapture);
return true;
} else if (obj.attachEvent){
return obj.attachEvent("on"+evt,fnc);
}
}
Ответ 2
Это вызывает дебаффер:
function debounce(callback, timeout, _this) {
var timer;
return function(e) {
var _that = this;
if (timer)
clearTimeout(timer);
timer = setTimeout(function() {
callback.call(_this || _that, e);
}, timeout);
}
}
Используется следующим образом:
// we'll attach the function created by "debounce" to each of the target
// user input events; this function only fires once 2 seconds have passed
// with no additional input; it can be attached to any number of desired
// events
var userAction = debounce(function(e) {
console.log("silence");
}, 2000);
document.addEventListener("mousemove", userAction, false);
document.addEventListener("click", userAction, false);
document.addEventListener("scroll", userAction, false);
Первое действие пользователя (mousemove, click или scroll) запускает функцию (прикрепленную к таймеру), которая сбрасывается каждый раз, когда происходит другое действие пользователя. Основной обратный вызов не срабатывает до тех пор, пока указанное количество времени не пройдет без каких-либо действий.
Обратите внимание, что нет глобальных флагов или переменных времени ожидания. Глобальный охват получает только ваш отмененный обратный вызов. Остерегайтесь решений, требующих обслуживания глобального состояния; они будут трудно рассуждать в контексте более крупного приложения.
Обратите внимание, что это решение полностью общее. Остерегайтесь решений, которые применяются только к вашему чрезвычайно узкому варианту использования.
Ответ 3
Большинство событий JavaScript bubble, поэтому вы можете сделать что-то вроде следующего:
- Придумайте список всех событий, которые вы считаете "активностью от пользователя" (например,
click
, mousemove
, keydown
и т.д.)
- Прикрепите одну функцию как прослушиватель событий для всех этих событий к
document
(или, возможно, document.body
для некоторых из них, я не могу вспомнить, если это проблема или нет).
- Когда прослушиватель запускается, пусть reset таймер с
clearTimeout
/setTimeout
Итак, у вас получится что-то вроде этого:
var events = ['click', 'mousemove', 'keydown'],
i = events.length,
timer,
delay = 10000,
logout = function () {
// do whatever it is you want to do
// after a period of inactivity
},
reset = function () {
clearTimeout(timer);
timer = setTimeout(logout, 10000);
};
while (i) {
i -= 1;
document.addEventListener(events[i], reset, false);
}
reset();
Обратите внимание, что есть некоторые проблемы, с которыми вам пришлось бы работать с приведенным выше кодом:
- Он не совместим с кросс-браузером. Он использует только
addEventListener
, поэтому он не будет работать в IE6-8
- Он загрязняет глобальное пространство имен. Он создает много избыточных переменных, которые могут конфликтовать с другими сценариями.
Это больше, чтобы дать вам представление о том, что вы можете сделать.
И теперь есть еще четыре ответа, но я уже набрал все это, так что: P
Ответ 4
Вы хотите отслеживать такие события, как mousemove
, keypress
, keydown
и/или click
на уровне документа.
Изменить:. Это приложение для смартфонов изменяет события, которые вы хотите прослушать. Учитывая ваши требования к текстовому поле и кнопке, я бы прослушал oninput
, а затем добавил вызов resetTimeout()
к обработчику кликов для вашей кнопки.
var inactivityTimeout = 0;
function resetTimeout() {
clearTimeout(inactivityTimeout);
inactivityTimeout = setTimeout(inactive, 300000);
}
function inactive() {
...
}
document.getElementById("chatInput").oninput = resetTimeout;
Ответ 5
Что-то вроде этого:
function onInactive(ms, cb){
var wait = setTimeout(cb, ms);
// Bind all events you consider as activity
// Note that binding this way overrides any previous events bound the same wa
// So if you already have events bound to document, use AddEventListener and AttachEvent instead
document.onmousemove = document.mousedown = document.mouseup = document.onkeydown = document.onkeyup = document.focus = function(){
clearTimeout(wait);
wait = setTimeout(cb, ms);
};
}
IE: http://jsfiddle.net/acNfy/
Активность в нижнем правом кадре будет задерживать обратный вызов.
Ответ 6
Я использую отличный метод "задержки" для этого, который я нашел в этом потоке
var delay = (function(){
var timer = 0;
return function(callback, ms){
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
})();
используйте как
delay(function(){ doSomethingWhenNoInputFor400ms(); },400);
Ответ 7
Кроме того, посмотрите jQuery idleTimer plugin от Paul Irish (jquery.idle-timer.js). Это было основано на Обнаружение, если пользователь не работает с JavaScript и YUI 3 (idle-timer.js).
Он смотрит на подобные события на другие ответы, плюс еще несколько.
events = 'mousemove keydown DOMMouseScroll mousewheel mousedown touchstart touchmove';
// activity is one of these events