import { APP_REGEX } from '@/app-config' import { effectDispose, unrefElement, isValueType } from '@/utils' import type { BasicTarget, QueryElementsOptions, ElementSelector, } from '@/types' import type { CSSProperties } from 'vue' /** * * @param target 目标元素或 ref 注册元素 * @param classNames 所需添加类名 * * @description * 为目标元素添加类名。 * * @example * // targetDom 当前 class: a-class b-class * setClass(targetDom, 'c-class') // a-class b-class c-class * setClass(targetDom, ['c-class', 'c-class']) // a-class b-class c-class */ export const setClass = ( target: BasicTarget, classNames: string | string[], ) => { const update = () => { const element = unrefElement(target) if (element) { const classes = typeof classNames === 'string' ? classNames.trim().split(' ') : classNames classes.forEach((item) => { if (item) { element.classList.add(item) } }) } } const watcher = watch(() => unrefElement(target), update, { immediate: true, }) effectDispose(watcher) } /** * * @param target 目标元素或 ref 注册元素 * @param className 所需删除类名 * * @description * 为目标元素删除类名。 * * @example * // targetDom 当前 class: a-class b-class * removeClass(targetDom, 'a-class') // b-class * removeClass(targetDom, ['a-class', 'b-class']) // null * removeClass(targetDom, 'removeAllClass') // null */ export const removeClass = ( target: BasicTarget, classNames: string | 'removeAllClass' | string[], ) => { const update = () => { const element = unrefElement(target) if (element) { if (classNames === 'removeAllClass') { const classList = element.classList classList.forEach((curr) => classList.remove(curr)) } else { const classes = typeof classNames === 'string' ? classNames.trim().split(' ') : classNames classes.forEach((item) => { if (item) { element.classList.remove(item) } }) } } } const watcher = watch(() => unrefElement(target), update, { immediate: true, }) effectDispose(watcher) } /** * * @param target 目标元素或 ref 注册元素 * @param className 查询元素是否含有此类名 * * @description * 查询元素是否含有此类名。 * * @example * hasClass(targetDom, 'matchClassName') // Ref | Ref * hasClass(targetDom, ['matchClassName', 'matchClassName']) // Ref | Ref */ export const hasClass = ( target: BasicTarget, classNames: string | string[], ) => { const hasClassRef = ref(false) const update = () => { const element = unrefElement(target) if (!element) { hasClassRef.value = false } else { const elementClassName = element.className const classes = typeof classNames === 'string' ? classNames .trim() .split(' ') .filter((curr: string) => curr !== '') : classNames hasClassRef.value = classes.some((curr) => elementClassName.includes(curr), ) } } const watcher = watch(() => unrefElement(target), update, { immediate: true, }) effectDispose(watcher) return hasClassRef } /** * * @param style 所需添加样式 * * @returns 添加前缀后的样式 * * @description * 为样式添加浏览器前缀,返回一个对象。 * * @example * autoPrefixStyle('transform') // {webkitTransform: 'transform', mozTransform: 'transform', msTransform: 'transform', oTransform: 'transform'} */ export const autoPrefixStyle = (style: string) => { const prefixes = ['webkit', 'moz', 'ms', 'o'] const styleWithPrefixes = {} prefixes.forEach((prefix) => { styleWithPrefixes[ `${prefix}${style.charAt(0).toUpperCase()}${style.slice(1)}` ] = style }) styleWithPrefixes[style] = style return styleWithPrefixes } /** * * @param target Target element dom * @param styles 所需绑定样式(如果为字符串, 则必须以分号结尾每个行内样式描述) * * @description * 为目标元素添加样式。 * * @example * style of string * ``` * const styles = 'width: 100px; height: 100px; background: red;' * * setStyle(styles) * ``` * style of object * ``` * const styles = { * width: '100px', * height: '100px', * } * * setStyle(styles) * ``` */ export const setStyle =