From 31b66263163b0c39015f000b91a221e19602b171 Mon Sep 17 00:00:00 2001 From: Jelf <353742991@qq.com> Date: Fri, 12 May 2023 21:20:23 +0800 Subject: [PATCH] feat(useElementByPoint): new `multiple` and `interval` options (#3089) --- packages/core/useElementByPoint/index.ts | 48 +++++++++++++++++++----- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/packages/core/useElementByPoint/index.ts b/packages/core/useElementByPoint/index.ts index f865f52d81d..d3136d7e883 100644 --- a/packages/core/useElementByPoint/index.ts +++ b/packages/core/useElementByPoint/index.ts @@ -1,13 +1,23 @@ +import type { Ref } from 'vue-demi' import { ref } from 'vue-demi' -import type { MaybeRefOrGetter } from '@vueuse/shared' -import { toValue } from '@vueuse/shared' +import type { MaybeRefOrGetter, Pausable } from '@vueuse/shared' +import { toValue, useIntervalFn } from '@vueuse/shared' import { useRafFn } from '../useRafFn' import type { ConfigurableDocument } from '../_configurable' import { defaultDocument } from '../_configurable' +import { useSupported } from '../useSupported' -export interface UseElementByPointOptions extends ConfigurableDocument { +export interface UseElementByPointOptions extends ConfigurableDocument { x: MaybeRefOrGetter y: MaybeRefOrGetter + multiple?: MaybeRefOrGetter + immediate?: boolean + interval?: 'requestAnimationFrame' | number +} + +export interface UseElementByPointReturn extends Pausable { + isSupported: Ref + element: Ref } /** @@ -16,19 +26,37 @@ export interface UseElementByPointOptions extends ConfigurableDocument { * @see https://vueuse.org/useElementByPoint * @param options - UseElementByPointOptions */ -export function useElementByPoint(options: UseElementByPointOptions) { - const element = ref(null) +export function useElementByPoint(options: UseElementByPointOptions): UseElementByPointReturn { + const { + x, y, + document = defaultDocument, + multiple, + interval = 'requestAnimationFrame', + immediate = true, + } = options - const { x, y, document = defaultDocument } = options + const isSupported = useSupported(() => { + if (toValue(multiple)) + return document && 'elementsFromPoint' in document - const controls = useRafFn(() => { - element.value = (document?.elementFromPoint(toValue(x), toValue(y)) || null) as HTMLElement | null + return document && 'elementFromPoint' in document }) + const element = ref(null) + + const cb = () => { + element.value = toValue(multiple) + ? document?.elementsFromPoint(toValue(x), toValue(y)) ?? [] + : document?.elementFromPoint(toValue(x), toValue(y)) ?? null + } + + const controls: Pausable = interval === 'requestAnimationFrame' + ? useRafFn(cb, { immediate }) + : useIntervalFn(cb, interval, { immediate }) + return { + isSupported, element, ...controls, } } - -export type UseElementByPointReturn = ReturnType