How to detect idle time in JavaScript elegantly?

前端 未结 30 2371
别跟我提以往
别跟我提以往 2020-11-21 11:51

Is it possible to detect \"idle\" time in JavaScript?
My primary use case probably would be to pre-fetch or preload content.

Idle time:

30条回答
  •  长发绾君心
    2020-11-21 12:39

    Based on the inputs provided by @equiman

    class _Scheduler {
        timeoutIDs;
    
        constructor() {
            this.timeoutIDs = new Map();
        }
    
        addCallback = (callback, timeLapseMS, autoRemove) => {
            if (!this.timeoutIDs.has(timeLapseMS + callback)) {
                let timeoutID = setTimeout(callback, timeLapseMS);
                this.timeoutIDs.set(timeLapseMS + callback, timeoutID);
            }
    
            if (autoRemove !== false) {
                setTimeout(
                    this.removeIdleTimeCallback, // Remove
                    10000 + timeLapseMS, // 10 secs after
                    callback, // the callback
                    timeLapseMS, // is invoked.
                );
            }
        };
    
        removeCallback = (callback, timeLapseMS) => {
            let timeoutID = this.timeoutIDs.get(timeLapseMS + callback);
            if (timeoutID) {
                clearTimeout(timeoutID);
                this.timeoutIDs.delete(timeLapseMS + callback);
            }
        };
    }
    
    class _IdleTimeScheduler extends _Scheduler {
        events = [
            'load',
            'mousedown',
            'mousemove',
            'keydown',
            'keyup',
            'input',
            'scroll',
            'touchstart',
            'touchend',
            'touchcancel',
            'touchmove',
        ];
        callbacks;
    
        constructor() {
            super();
            this.events.forEach(name => {
                document.addEventListener(name, this.resetTimer, true);
            });
    
            this.callbacks = new Map();
        }
    
        addIdleTimeCallback = (callback, timeLapseMS) => {
            this.addCallback(callback, timeLapseMS, false);
    
            let callbacksArr = this.callbacks.get(timeLapseMS);
            if (!callbacksArr) {
                this.callbacks.set(timeLapseMS, [callback]);
            } else {
                if (!callbacksArr.includes(callback)) {
                    callbacksArr.push(callback);
                }
            }
        };
    
        removeIdleTimeCallback = (callback, timeLapseMS) => {
            this.removeCallback(callback, timeLapseMS);
    
            let callbacksArr = this.callbacks.get(timeLapseMS);
            if (callbacksArr) {
                let index = callbacksArr.indexOf(callback);
                if (index !== -1) {
                    callbacksArr.splice(index, 1);
                }
            }
        };
    
        resetTimer = () => {
            for (let [timeLapseMS, callbacksArr] of this.callbacks) {
                callbacksArr.forEach(callback => {
                    // Clear the previous IDs
                    let timeoutID = this.timeoutIDs.get(timeLapseMS + callback);
                    clearTimeout(timeoutID);
    
                    // Create new timeout IDs.
                    timeoutID = setTimeout(callback, timeLapseMS);
                    this.timeoutIDs.set(timeLapseMS + callback, timeoutID);
                });
            }
        };
    }
    export const Scheduler = new _Scheduler();
    export const IdleTimeScheduler = new _IdleTimeScheduler();
    

提交回复
热议问题