源码解读
useEventListener:事件监听
主要逻辑就是,useEffect addEventListener 注册事件,return 的时候 removeEventListener
useClickAway:监听目标元素外的点击时间
Node.contains() 返回一个布尔值,来表示传入的节点是否为该节点的后代节点,主要用这个 API 来判断是不是点击到了某个元素的内部
https://developer.mozilla.org/zh-CN/docs/Web/API/Node/contains
export default function useClickAway<T extends Event = Event>(onClickAway: (event: T) => void,target: BasicTarget | BasicTarget[],eventName: string = 'click',) {const onClickAwayRef = useLatest(onClickAway);useEffectWithTarget(() => {const handler = (event: any) => {const targets = Array.isArray(target) ? target : [target];// 使用 some,有一个满足了,说明就是点击内部了,直接 return 不执行 callbackif (targets.some((item) => {const targetElement = getTargetElement(item);// 这里用 contains 判断是否点击到内部return !targetElement || targetElement?.contains(event.target);})) {return;}onClickAwayRef.current(event);};document.addEventListener(eventName, handler);return () => {document.removeEventListener(eventName, handler);};},[eventName],target,);}
useDocumentVisibility:监听当前页面是否可见
主要使用 document.visibilityState 属性,返回当前 document 的可见性:https://developer.mozilla.org/zh-CN/docs/Web/API/Document/visibilityState,同时可以监听 visibilitychange 事件
type VisibilityState = 'hidden' | 'visible' | 'prerender' | undefined;const getVisibility = () => {if (!isBrowser) {return 'visible';}return document.visibilityState;};function useDocumentVisibility(): VisibilityState {// 获取初始值const [documentVisibility, setDocumentVisibility] = useState(() => getVisibility());// 监听事件useEventListener('visibilitychange',() => {setDocumentVisibility(getVisibility());},{target: () => document,},);return documentVisibility;}
useDrop
useDrag
useTitle:设置页面标题
import { useEffect, useRef } from 'react';import useUnmount from '../useUnmount';import isBrowser from '../utils/isBrowser';export interface Options {restoreOnUnmount?: boolean;}const DEFAULT_OPTIONS: Options = {restoreOnUnmount: false,};function useTitle(title: string, options: Options = DEFAULT_OPTIONS) {const titleRef = useRef(isBrowser ? document.title : '');useEffect(() => {document.title = title;}, [title]);// 组件卸载时,返回上一个页面标题useUnmount(() => {if (options.restoreOnUnmount) {document.title = titleRef.current;}});}export default useTitle;
