背景
偶然间,在使用一款google插件的时候,发现它有一个小功能,只要我停留在它的页面不操作10分钟以上,就会自动给我打开一个屏保界面,这样的
目的
这种华而不实的功能,正好适合个人博客,所以我就自己简单实现了一下
核心思路
监听用户当前是否出于活跃状态,这里的活跃状态包含以下几种
- 是否出发滚动;
- 是否移动或者点击鼠标;
- 是否按下键盘;
- 是否离开(或隐藏)当前窗口(可选)
监听用户以上的事件,来判断是否在一段时间内,用户是处于活跃状态的
下面useListenPage的hook中,会监听以上几种事件
代码如下
代码其实就很简单了,这里我直接写了一个hook,方便后续扩展和使用。
hooks的功能:在一段时间内,返回用户是否活跃状态的布尔值
import { useState } from "react";
import { useMount } from "./useMount";
import { useUnMount } from "./useUnMount";
import { debounce } from '../utils';const defaultDelay = 10000;interface IUseListenPage {/** 空闲时间, 默认10s不操作就进入不活跃状态 */delay?: number;/** 是否页面不可见时,设置为不活跃 */isHidden?: boolean;
}export function useListenPage(props: IUseListenPage) {const { delay = defaultDelay, isHidden = false } = props;const [isActive, setIsActive] = useState(true);let timer: any = null;const startListener = () => { if (timer) clearTimeout(timer);timer = setTimeout(() => {if (isActive) {setIsActive(false);}}, delay);}const handleAction = () => {setIsActive(true);/** 重新开启监听 */startListener();}const handleVisibilityChange = () => {if (document.hidden && isActive && isHidden) {// 页面不可见时,设置为不活跃setIsActive(false);}}useMount(() => {/** 开始监听 */startListener();/** 监听页面是否可见 */window.addEventListener("visibilitychange", handleVisibilityChange)/** 监听 滚动 鼠标 键盘事件 */window.addEventListener("scroll", debounce(handleAction));window.addEventListener("mousemove", debounce(handleAction));window.addEventListener("keydown", debounce(handleAction));window.addEventListener("click", debounce(handleAction));})useUnMount(() => {/** 移除监听 */window.removeEventListener("visibilitychange", handleVisibilityChange)window.removeEventListener("scroll", debounce(handleAction));window.removeEventListener("mousemove", debounce(handleAction));window.removeEventListener("keydown", debounce(handleAction));window.removeEventListener("click", debounce(handleAction));})return isActive;
}
使用如下
function xxx({children}: any) {const isActive = useListenPage({ delay: 15 * 60 * 1000 });return isActive ? children : <ScreenSaver />;
}
写在最后
如果觉得这种小知识有帮助到大家,那就点个赞吧,让博主开心开心!
大家有遇到什么问题的,都可以在评论区发出来,只要博主有时间,一定帮你们解决目前的问题,任何相关大前端的疑难杂症都可