监听页面元素外的点击是一个很常见的需求,多用于浮窗的隐藏。要实现这样一个功能其实要远比想象的简单。
export function useClickAway(target:| Element| Ref<Element | undefined>| Array<Element | Ref<Element | undefined>>,listener: EventListener,options: UseClickAwayOptions = {}) {if (!inBrowser) {return;}const { eventName = 'click' } = options;const onClick = (event: Event) => {const targets = Array.isArray(target) ? target : [target];const isClickAway = targets.every((item) => {const element = unref(item);return element && !element.contains(event.target as Node);});if (isClickAway) {listener(event);}};useEventListener(eventName, onClick, { target: document });}export type UseClickAwayOptions = {eventName?: string;};export function useEventListener<K extends keyof DocumentEventMap>(type: K,listener: (event: DocumentEventMap[K]) => void,options?: UseEventListenerOptions): void;
首先确认参数 target 可以是单个的 Element 或者多个 Element 组成的数组。因为触发事件默认采取时间冒泡流,所以我们只需要对 document 进行监听,获取当前的 evt.target 并通过 Node.contains() 来判断当前点击的位置是否为目标元素 target 本身或者其子元素。这样就可以检测出点击操作是否触发在目标区域之外,若是的话再去触发添加的监听函数。
