Вы попросили элегантности, и я создал простой класс, который также поддерживает ленивую проверку (которая имеет состояние ожидания), кроме императивного способа (с обратными вызовами). Кроме того, этот класс поддерживает "backToActive", когда нарушается время простоя.
class Idle {
constructor(timeout = 10, idleCallback = null, backToActiveCallback = null, autoStart = true, backToActiveOnXHR = false) {
this.timeout = timeout
this.idleCallback = idleCallback
this.backToActiveCallback = backToActiveCallback
this.autoStart = autoStart // only F5
this.backToActiveOnXHR = backToActiveOnXHR
this.idle = false
this.timer = null
this.events = ['scroll', 'mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart']
this.init()
}
init() {
if(this.backToActiveOnXHR) {
this.events.push('load')
}
this.events.forEach(name => {
window.addEventListener(name, this.backToActive, true)
})
if(this.autoStart) {
this.backToActive()
}
}
goIdle = () => {
this.idle = true
if(!!this.idleCallback) {
this.idleCallback(this.timeout)
}
}
backToActive = () => {
if(this.idle) {
this.backToActiveCallback()
}
this.idle = false
clearTimeout(this.timer)
this.timer = setTimeout(this.goIdle, this.timeout * 1000)
}
}
Использование:
let idleCallback = timeout => { console.log(`Went idle after ${timeout} seconds`) }
let backToActiveCallback = () => { console.log('Back to active') }
let idle = new Idle(30, idleCallback, backToActiveCallback)
Результат в devtools:
// Went idle after 30 seconds <--- goes idle when no activity is detected
// Back to active <--- when the user is detected again
Преимущество поддержки лени:
setInterval(() => {
common.fetchApi('/api/v1/list', { status: idle.idle ? 'away' : 'online' }).then(/* show a list of elements */)
}, 1000 * 5)
Зачем вам ленивый чек? Иногда мы используем периодический XHR (с setInterval), то есть когда пользователь просматривает список рейсов, поездок, фильмов, заказов и т. Д. С каждым XHR мы затем можем добавлять информацию о его статусе активности (онлайн / нет), поэтому у нас есть Чувство активных пользователей в нашей системе.
Мой класс основан на ответах Эквимана и Фрэнка Конейна.