dom.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import { ref, onMounted, computed } from 'vue'
  2. import { toRawType } from './'
  3. /**
  4. * 获取真实DOM的高度
  5. * @returns [heightRef, VMRef, readyRef]
  6. */
  7. export const getVMDomWH = attr => {
  8. const origin = ref(0)
  9. const domRef = ref(null)
  10. const ready = ref(false)
  11. const referWH = () => {
  12. origin.value = 0
  13. ready.value = false
  14. if (domRef.value) {
  15. setTimeout(() => {
  16. origin.value = attr === 'width' ? domRef.value.offsetWidth : domRef.value.offsetHeight
  17. setTimeout(() => (ready.value = true))
  18. })
  19. }
  20. }
  21. onMounted(referWH)
  22. return [origin, domRef, ready, referWH]
  23. }
  24. /**
  25. * 生成切换高度的方法
  26. * @returns [VMRef, fn, maxHeightRef, originHeightRef, showRef, readyRef]
  27. */
  28. export const changeWHFactory = (isShow = false, attr = 'height') => {
  29. const [origin, domRef, ready, referWH] = getVMDomWH(attr)
  30. const max = ref(0)
  31. const show = computed({
  32. get: () => {
  33. return max.value == origin.value
  34. },
  35. set: val => {
  36. max.value = val ? origin.value : 0
  37. },
  38. })
  39. const changeShow = (val = !show.value) => {
  40. show.value = val
  41. }
  42. onMounted(() => {
  43. show.value = isShow
  44. })
  45. return [domRef, changeShow, max, origin, show, ready, referWH]
  46. }
  47. /**
  48. * 获取父级滚动
  49. * @param {*} node
  50. * @returns
  51. */
  52. export const getScrollParent = node => {
  53. if (node == null) {
  54. return null
  55. }
  56. if (node === document.documentElement) {
  57. return node
  58. }
  59. const cssScrollY = getComputedStyle(node).overflowY
  60. const cssScrollX = getComputedStyle(node).overflowX
  61. if (node.scrollHeight > node.clientHeight || cssScrollY === 'auto' || cssScrollY === 'scroll' || cssScrollX === 'auto' || cssScrollX === 'scroll') {
  62. return node
  63. } else {
  64. return getScrollParent(node.parentNode)
  65. }
  66. }
  67. /**
  68. * 获取所有父级滚动
  69. * @param {*} origin
  70. * @param {*} target
  71. */
  72. export const getScrollParents = (origin, target) => {
  73. const parents = []
  74. let temporary = origin
  75. while (temporary && temporary !== target && temporary !== document.documentElement && target.contains(temporary)) {
  76. const scrollParent = getScrollParent(temporary)
  77. if (scrollParent) {
  78. if (scrollParent !== origin) {
  79. parents.push(scrollParent)
  80. }
  81. temporary = scrollParent.parentNode
  82. } else {
  83. break
  84. }
  85. }
  86. return parents
  87. }
  88. /**
  89. * 获取制定dom在相对于目标中的位置
  90. * @param {*} origin 或获取的DOM
  91. * @param {*} target 目标DOM
  92. * @param {*} isIncludeSelf 是否要包含自身宽高
  93. * @returns 位置信息 {x, y}
  94. */
  95. export const getPostionByTarget = (origin, target, isIncludeSelf = false) => {
  96. const pos = { x: 0, y: 0, width: origin.offsetWidth, height: origin.offsetHeight }
  97. let temporary = origin
  98. while (temporary && temporary !== target && temporary !== document.documentElement && target.contains(temporary)) {
  99. pos.x += temporary.offsetLeft + temporary.clientLeft
  100. pos.y += temporary.offsetTop + temporary.clientTop
  101. temporary = temporary.offsetParent
  102. }
  103. if (isIncludeSelf) {
  104. pos.x += pos.width
  105. pos.y += pos.height
  106. }
  107. return pos
  108. }
  109. export const normalizeUnitToStyle = unit => {
  110. if (unit === void 0) {
  111. return unit
  112. } else if (toRawType(unit) === 'Number') {
  113. return unit ? ((unit <= 1) & (unit >= 0) ? 100 * unit + '%' : unit + 'px') : void 0
  114. } else if (unit.includes('px')) {
  115. return normalizeUnitToStyle(parseFloat(unit))
  116. } else if (unit.includes('%')) {
  117. return normalizeUnitToStyle(parseFloat(unit) / 100)
  118. } else {
  119. return unit
  120. }
  121. }