dom.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. import XEUtils from 'xe-utils'
  2. export const browse = XEUtils.browse()
  3. const reClsMap = {}
  4. function getClsRE (cls) {
  5. if (!reClsMap[cls]) {
  6. reClsMap[cls] = new RegExp(`(?:^|\\s)${cls}(?!\\S)`, 'g')
  7. }
  8. return reClsMap[cls]
  9. }
  10. function getNodeOffset (elem, container, rest) {
  11. if (elem) {
  12. const parentElem = elem.parentNode
  13. rest.top += elem.offsetTop
  14. rest.left += elem.offsetLeft
  15. if (parentElem && parentElem !== document.documentElement && parentElem !== document.body) {
  16. rest.top -= parentElem.scrollTop
  17. rest.left -= parentElem.scrollLeft
  18. }
  19. if (container && (elem === container || elem.offsetParent === container) ? 0 : elem.offsetParent) {
  20. return getNodeOffset(elem.offsetParent, container, rest)
  21. }
  22. }
  23. return rest
  24. }
  25. function isScale (val) {
  26. return val && /^\d+%$/.test(val)
  27. }
  28. function hasClass (elem, cls) {
  29. return elem && elem.className && elem.className.match && elem.className.match(getClsRE(cls))
  30. }
  31. function removeClass (elem, cls) {
  32. if (elem && hasClass(elem, cls)) {
  33. elem.className = elem.className.replace(getClsRE(cls), '')
  34. }
  35. }
  36. function getDomNode () {
  37. const documentElement = document.documentElement
  38. const bodyElem = document.body
  39. return {
  40. scrollTop: documentElement.scrollTop || bodyElem.scrollTop,
  41. scrollLeft: documentElement.scrollLeft || bodyElem.scrollLeft,
  42. visibleHeight: documentElement.clientHeight || bodyElem.clientHeight,
  43. visibleWidth: documentElement.clientWidth || bodyElem.clientWidth
  44. }
  45. }
  46. export function getOffsetHeight (elem) {
  47. return elem ? elem.offsetHeight : 0
  48. }
  49. export function getPaddingTopBottomSize (elem) {
  50. if (elem) {
  51. const computedStyle = getComputedStyle(elem)
  52. const paddingTop = XEUtils.toNumber(computedStyle.paddingTop)
  53. const paddingBottom = XEUtils.toNumber(computedStyle.paddingBottom)
  54. return paddingTop + paddingBottom
  55. }
  56. return 0
  57. }
  58. export function setScrollTop (elem, scrollTop) {
  59. if (elem) {
  60. elem.scrollTop = scrollTop
  61. }
  62. }
  63. export function setScrollLeft (elem, scrollLeft) {
  64. if (elem) {
  65. elem.scrollLeft = scrollLeft
  66. }
  67. }
  68. // export function setScrollLeftAndTop (elem, scrollLeft, scrollTop) {
  69. // if (elem) {
  70. // elem.scrollLeft = scrollLeft
  71. // elem.scrollTop = scrollTop
  72. // }
  73. // }
  74. function isNodeElement (elem) {
  75. return elem && elem.nodeType === 1
  76. }
  77. export const DomTools = {
  78. browse,
  79. isPx (val) {
  80. return val && /^\d+(px)?$/.test(val)
  81. },
  82. isScale,
  83. hasClass,
  84. removeClass,
  85. addClass (elem, cls) {
  86. if (elem && !hasClass(elem, cls)) {
  87. removeClass(elem, cls)
  88. elem.className = `${elem.className} ${cls}`
  89. }
  90. },
  91. updateCellTitle (overflowElem, column) {
  92. const content = column.type === 'html' ? overflowElem.innerText : overflowElem.textContent
  93. if (overflowElem.getAttribute('title') !== content) {
  94. overflowElem.setAttribute('title', content)
  95. }
  96. },
  97. getDomNode,
  98. /**
  99. * 检查触发源是否属于目标节点
  100. */
  101. getEventTargetNode (evnt, container, queryCls, queryMethod) {
  102. let targetElem
  103. let target = evnt.target
  104. while (target && target.nodeType && target !== document) {
  105. if (queryCls && hasClass(target, queryCls) && (!queryMethod || queryMethod(target))) {
  106. targetElem = target
  107. } else if (target === container) {
  108. return { flag: queryCls ? !!targetElem : true, container, targetElem: targetElem }
  109. }
  110. target = target.parentNode
  111. }
  112. return { flag: false }
  113. },
  114. /**
  115. * 获取元素相对于 document 的位置
  116. */
  117. getOffsetPos (elem, container) {
  118. return getNodeOffset(elem, container, { left: 0, top: 0 })
  119. },
  120. getAbsolutePos (elem) {
  121. const bounding = elem.getBoundingClientRect()
  122. const boundingTop = bounding.top
  123. const boundingLeft = bounding.left
  124. const { scrollTop, scrollLeft, visibleHeight, visibleWidth } = getDomNode()
  125. return { boundingTop, top: scrollTop + boundingTop, boundingLeft, left: scrollLeft + boundingLeft, visibleHeight, visibleWidth }
  126. },
  127. scrollToView (elem) {
  128. const scrollIntoViewIfNeeded = 'scrollIntoViewIfNeeded'
  129. const scrollIntoView = 'scrollIntoView'
  130. if (elem) {
  131. if (elem[scrollIntoViewIfNeeded]) {
  132. elem[scrollIntoViewIfNeeded]()
  133. } else if (elem[scrollIntoView]) {
  134. elem[scrollIntoView]()
  135. }
  136. }
  137. },
  138. triggerEvent (targetElem, type) {
  139. if (targetElem) {
  140. targetElem.dispatchEvent(new Event(type))
  141. }
  142. },
  143. calcHeight ($xetable, key) {
  144. const val = $xetable[key]
  145. let num = 0
  146. if (val) {
  147. if (val === 'auto') {
  148. num = $xetable.parentHeight
  149. } else {
  150. const excludeHeight = $xetable.getExcludeHeight()
  151. if (isScale(val)) {
  152. num = Math.floor((XEUtils.toInteger(val) || 1) / 100 * $xetable.parentHeight)
  153. } else {
  154. num = XEUtils.toNumber(val)
  155. }
  156. num = Math.max(40, num - excludeHeight)
  157. }
  158. }
  159. return num
  160. },
  161. isNodeElement
  162. }
  163. export default DomTools