style.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import { isClient } from '@vueuse/core'
  2. import { isNumber, isObject, isString } from '../types'
  3. import { camelize } from '../strings'
  4. import { entriesOf, keysOf } from '../objects'
  5. import { debugWarn } from '../error'
  6. import type { CSSProperties } from 'vue'
  7. const SCOPE = 'utils/dom/style'
  8. export const classNameToArray = (cls = '') => cls.split(' ').filter(item => !!item.trim())
  9. export const hasClass = (el: Element, cls: string): boolean => {
  10. if (!el || !cls) return false
  11. if (cls.includes(' ')) throw new Error('className should not contain space.')
  12. return el.classList.contains(cls)
  13. }
  14. export const addClass = (el: Element, cls: string) => {
  15. if (!el || !cls.trim()) return
  16. el.classList.add(...classNameToArray(cls))
  17. }
  18. export const removeClass = (el: Element, cls: string) => {
  19. if (!el || !cls.trim()) return
  20. el.classList.remove(...classNameToArray(cls))
  21. }
  22. export const getStyle = (element: HTMLElement, styleName: keyof CSSProperties): string => {
  23. if (!isClient || !element || !styleName) return ''
  24. let key = camelize(styleName)
  25. if (key === 'float') key = 'cssFloat'
  26. try {
  27. const style = (element.style as any)[key]
  28. if (style) return style
  29. const computed: any = document.defaultView?.getComputedStyle(element, '')
  30. return computed ? computed[key] : ''
  31. } catch {
  32. return (element.style as any)[key]
  33. }
  34. }
  35. export const setStyle = (element: HTMLElement, styleName: CSSProperties | keyof CSSProperties, value?: string | number) => {
  36. if (!element || !styleName) return
  37. if (isObject(styleName)) {
  38. entriesOf(styleName).forEach(([prop, value]) => setStyle(element, prop, value))
  39. } else {
  40. const key: any = camelize(styleName)
  41. element.style[key] = value as any
  42. }
  43. }
  44. export const removeStyle = (element: HTMLElement, style: CSSProperties | keyof CSSProperties) => {
  45. if (!element || !style) return
  46. if (isObject(style)) {
  47. keysOf(style).forEach(prop => removeStyle(element, prop))
  48. } else {
  49. setStyle(element, style, '')
  50. }
  51. }
  52. export function addUnit(value?: string | number, defaultUnit = 'px') {
  53. if (!value) return ''
  54. if (isString(value)) {
  55. return value
  56. } else if (isNumber(value)) {
  57. return `${value}${defaultUnit}`
  58. }
  59. debugWarn(SCOPE, 'binding value must be a string or number')
  60. }