From 15895d6d4d1caa0830385fe49365c4f3b01fab49 Mon Sep 17 00:00:00 2001 From: btea <2356281422@qq.com> Date: Sat, 26 Feb 2022 15:00:57 +0800 Subject: [PATCH] refactor(utils): extract `isElement` (#6292) --- packages/components/image/src/image.vue | 11 ++++++----- packages/components/message/src/message-method.ts | 5 +++-- packages/components/notification/src/notify.ts | 8 ++++---- packages/components/popper/src/trigger.vue | 3 ++- packages/components/popper/src/utils.ts | 4 +++- packages/directives/click-outside/index.ts | 8 ++++---- packages/utils/types.ts | 2 ++ 7 files changed, 24 insertions(+), 17 deletions(-) diff --git a/packages/components/image/src/image.vue b/packages/components/image/src/image.vue index c851507e28..7434c8968c 100644 --- a/packages/components/image/src/image.vue +++ b/packages/components/image/src/image.vue @@ -49,14 +49,15 @@ import { useDeprecated, } from '@element-plus/hooks' import ImageViewer from '@element-plus/components/image-viewer' -import { getScrollContainer, isInContainer } from '@element-plus/utils' +import { + getScrollContainer, + isInContainer, + isElement, +} from '@element-plus/utils' import { imageEmits, imageProps } from './image' import type { CSSProperties, StyleValue } from 'vue' -const isHtmlElement = (e: any): e is Element => - e && e.nodeType === Node.ELEMENT_NODE - let prevOverflow = '' export default defineComponent({ @@ -186,7 +187,7 @@ export default defineComponent({ await nextTick() const { scrollContainer } = props - if (isHtmlElement(scrollContainer)) { + if (isElement(scrollContainer)) { _scrollContainer.value = scrollContainer } else if (isString(scrollContainer) && scrollContainer !== '') { _scrollContainer.value = diff --git a/packages/components/message/src/message-method.ts b/packages/components/message/src/message-method.ts index 5176e49c52..a5b1523e45 100644 --- a/packages/components/message/src/message-method.ts +++ b/packages/components/message/src/message-method.ts @@ -5,6 +5,7 @@ import { isNumber, isObject, isString, + isElement, debugWarn, } from '@element-plus/utils' import { useZIndex } from '@element-plus/hooks' @@ -78,13 +79,13 @@ const message: MessageFn & Partial & { _context: AppContext | null } = } let appendTo: HTMLElement | null = document.body - if (options.appendTo instanceof HTMLElement) { + if (isElement(options.appendTo)) { appendTo = options.appendTo } else if (isString(options.appendTo)) { appendTo = document.querySelector(options.appendTo) } // should fallback to default value with a warning - if (!(appendTo instanceof HTMLElement)) { + if (!isElement(appendTo)) { debugWarn( 'ElMessage', 'the appendTo option is not an HTMLElement. Falling back to document.body.' diff --git a/packages/components/notification/src/notify.ts b/packages/components/notification/src/notify.ts index fb283c9803..b26ca8b7ec 100644 --- a/packages/components/notification/src/notify.ts +++ b/packages/components/notification/src/notify.ts @@ -1,7 +1,7 @@ import { createVNode, render } from 'vue' import { isClient } from '@vueuse/core' import { useZIndex } from '@element-plus/hooks' -import { isVNode, debugWarn } from '@element-plus/utils' +import { isVNode, isElement, isString, debugWarn } from '@element-plus/utils' import NotificationConstructor from './notification.vue' import { notificationTypes } from './notification' @@ -60,14 +60,14 @@ const notify: NotifyFn & Partial = function (options = {}) { } let appendTo: HTMLElement | null = document.body - if (options.appendTo instanceof HTMLElement) { + if (isElement(options.appendTo)) { appendTo = options.appendTo - } else if (typeof options.appendTo === 'string') { + } else if (isString(options.appendTo)) { appendTo = document.querySelector(options.appendTo) } // should fallback to default value with a warning - if (!(appendTo instanceof HTMLElement)) { + if (!isElement(appendTo)) { debugWarn( 'ElNotification', 'the appendTo option is not an HTMLElement. Falling back to document.body.' diff --git a/packages/components/popper/src/trigger.vue b/packages/components/popper/src/trigger.vue index ce45cdd09c..e1bd5f19de 100644 --- a/packages/components/popper/src/trigger.vue +++ b/packages/components/popper/src/trigger.vue @@ -12,6 +12,7 @@ import { defineComponent, inject, watch } from 'vue' import { ElOnlyChild } from '@element-plus/components/slot' import { useForwardRef } from '@element-plus/hooks' +import { isElement } from '@element-plus/utils' import { usePopperTriggerProps } from './popper' import { POPPER_INJECTION_KEY } from './tokens' import { unwrapMeasurableEl } from './utils' @@ -51,7 +52,7 @@ export default defineComponent({ watch( () => triggerRef.value, (el, prevEl) => { - if (el && el instanceof HTMLElement) { + if (isElement(el)) { ;[ 'onMouseenter', 'onMouseleave', diff --git a/packages/components/popper/src/utils.ts b/packages/components/popper/src/utils.ts index 20d723cc8d..41960fdc1d 100644 --- a/packages/components/popper/src/utils.ts +++ b/packages/components/popper/src/utils.ts @@ -1,3 +1,5 @@ +import { isElement } from '@element-plus/utils' + import type { ComponentPublicInstance } from 'vue' import type { UsePopperCoreConfigProps, Measurable } from './popper' @@ -29,7 +31,7 @@ export const unwrapMeasurableEl = ( let el: HTMLElement | null = null if (!$el) return null - if ('getBoundingClientRect' in $el || ($el as any) instanceof HTMLElement) { + if ('getBoundingClientRect' in $el || isElement($el)) { el = $el as HTMLElement } else { // refs can be Vue component diff --git a/packages/directives/click-outside/index.ts b/packages/directives/click-outside/index.ts index 284459c8b9..39f46930d4 100644 --- a/packages/directives/click-outside/index.ts +++ b/packages/directives/click-outside/index.ts @@ -1,5 +1,5 @@ import { isClient } from '@vueuse/core' -import { on } from '@element-plus/utils' +import { isElement } from '@element-plus/utils' import type { ComponentPublicInstance, @@ -22,8 +22,8 @@ const nodeList: FlushList = new Map() let startClick: MouseEvent if (isClient) { - on(document, 'mousedown', (e: MouseEvent) => (startClick = e)) - on(document, 'mouseup', (e: MouseEvent) => { + document.addEventListener('mousedown', (e: MouseEvent) => (startClick = e)) + document.addEventListener('mouseup', (e: MouseEvent) => { for (const handlers of nodeList.values()) { for (const { documentHandler } of handlers) { documentHandler(e as MouseEvent, startClick) @@ -39,7 +39,7 @@ function createDocumentHandler( let excludes: HTMLElement[] = [] if (Array.isArray(binding.arg)) { excludes = binding.arg - } else if ((binding.arg as unknown) instanceof HTMLElement) { + } else if (isElement(binding.arg)) { // due to current implementation on binding type is wrong the type casting is necessary here excludes.push(binding.arg as unknown as HTMLElement) } diff --git a/packages/utils/types.ts b/packages/utils/types.ts index 32cdcabe54..a9715e7ad2 100644 --- a/packages/utils/types.ts +++ b/packages/utils/types.ts @@ -18,3 +18,5 @@ export const isEmpty = (val: unknown) => (!val && val !== 0) || (isArray(val) && val.length === 0) || (isObject(val) && !Object.keys(val).length) + +export const isElement = (e: unknown): e is Element => e instanceof Element