diff --git a/hooks/useIdle/index.d.ts b/hooks/useIdle/index.d.ts new file mode 100644 index 0000000..1ca791c --- /dev/null +++ b/hooks/useIdle/index.d.ts @@ -0,0 +1,11 @@ +export interface UseIdleOptions { + /** 空闲超时时间(毫秒),默认值 10000 */ + timeout?: number; + /** 监听的事件列表,默认值 ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart', 'wheel'] */ + events?: string[]; +} + +/** + * 检测用户是否处于空闲状态 + */ +export default function useIdle(options?: UseIdleOptions): boolean; diff --git a/hooks/useIdle/index.js b/hooks/useIdle/index.js new file mode 100644 index 0000000..d583540 --- /dev/null +++ b/hooks/useIdle/index.js @@ -0,0 +1,51 @@ +import { useEffect, useState } from "react"; + +/** + * 检测用户是否处于空闲状态 + */ +function useIdle(options = {}) { + const { + timeout = 10000, + events = [ + "mousedown", + "mousemove", + "keypress", + "scroll", + "touchstart", + "wheel", + ], + } = options; + + const [isIdle, setIsIdle] = useState(false); + + useEffect(() => { + let idleTimer; + + // 重置空闲计时器 + const resetTimer = () => { + setIsIdle(false); + clearTimeout(idleTimer); + idleTimer = setTimeout(() => setIsIdle(true), timeout); + }; + + // 初始化计时器 + resetTimer(); + + // 添加事件监听器 + events.forEach((event) => { + window.addEventListener(event, resetTimer, { passive: true }); + }); + + // 清理函数 + return () => { + clearTimeout(idleTimer); + events.forEach((event) => { + window.removeEventListener(event, resetTimer); + }); + }; + }, [timeout, events]); + + return isIdle; +} + +export default useIdle;