style.ts 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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 = (
  36. element: HTMLElement,
  37. styleName: CSSProperties | keyof CSSProperties,
  38. value?: string | number,
  39. ) => {
  40. if (!element || !styleName) return;
  41. if (isObject(styleName)) {
  42. entriesOf(styleName).forEach(([prop, value]) => setStyle(element, prop, value));
  43. } else {
  44. const key: any = camelize(styleName);
  45. element.style[key] = value as any;
  46. }
  47. };
  48. export const removeStyle = (element: HTMLElement, style: CSSProperties | keyof CSSProperties) => {
  49. if (!element || !style) return;
  50. if (isObject(style)) {
  51. keysOf(style).forEach((prop) => removeStyle(element, prop));
  52. } else {
  53. setStyle(element, style, '');
  54. }
  55. };
  56. export function addUnit(value?: string | number, defaultUnit = 'px') {
  57. if (!value) return '';
  58. if (isString(value)) {
  59. return value;
  60. } else if (isNumber(value)) {
  61. return `${value}${defaultUnit}`;
  62. }
  63. debugWarn(SCOPE, 'binding value must be a string or number');
  64. }