import { ref, onMounted, computed } from 'vue' import { toRawType } from './' /** * 获取真实DOM的高度 * @returns [heightRef, VMRef, readyRef] */ export const getVMDomWH = attr => { const origin = ref(0) const domRef = ref(null) const ready = ref(false) const referWH = () => { origin.value = 0 ready.value = false if (domRef.value) { setTimeout(() => { origin.value = attr === 'width' ? domRef.value.offsetWidth : domRef.value.offsetHeight setTimeout(() => (ready.value = true)) }) } } onMounted(referWH) return [origin, domRef, ready, referWH] } /** * 生成切换高度的方法 * @returns [VMRef, fn, maxHeightRef, originHeightRef, showRef, readyRef] */ export const changeWHFactory = (isShow = false, attr = 'height') => { const [origin, domRef, ready, referWH] = getVMDomWH(attr) const max = ref(0) const show = computed({ get: () => { return max.value == origin.value }, set: val => { max.value = val ? origin.value : 0 }, }) const changeShow = (val = !show.value) => { show.value = val } onMounted(() => { show.value = isShow }) return [domRef, changeShow, max, origin, show, ready, referWH] } /** * 获取父级滚动 * @param {*} node * @returns */ export const getScrollParent = node => { if (node == null) { return null } if (node === document.documentElement) { return node } const cssScrollY = getComputedStyle(node).overflowY const cssScrollX = getComputedStyle(node).overflowX if (node.scrollHeight > node.clientHeight || cssScrollY === 'auto' || cssScrollY === 'scroll' || cssScrollX === 'auto' || cssScrollX === 'scroll') { return node } else { return getScrollParent(node.parentNode) } } /** * 获取所有父级滚动 * @param {*} origin * @param {*} target */ export const getScrollParents = (origin, target) => { const parents = [] let temporary = origin while (temporary && temporary !== target && temporary !== document.documentElement && target.contains(temporary)) { const scrollParent = getScrollParent(temporary) if (scrollParent) { if (scrollParent !== origin) { parents.push(scrollParent) } temporary = scrollParent.parentNode } else { break } } return parents } /** * 获取制定dom在相对于目标中的位置 * @param {*} origin 或获取的DOM * @param {*} target 目标DOM * @param {*} isIncludeSelf 是否要包含自身宽高 * @returns 位置信息 {x, y} */ export const getPostionByTarget = (origin, target, isIncludeSelf = false) => { const pos = { x: 0, y: 0, width: origin.offsetWidth, height: origin.offsetHeight } let temporary = origin while (temporary && temporary !== target && temporary !== document.documentElement && target.contains(temporary)) { pos.x += temporary.offsetLeft + temporary.clientLeft pos.y += temporary.offsetTop + temporary.clientTop temporary = temporary.offsetParent } if (isIncludeSelf) { pos.x += pos.width pos.y += pos.height } return pos } export const normalizeUnitToStyle = unit => { if (unit === void 0) { return unit } else if (toRawType(unit) === 'Number') { return unit ? ((unit <= 1) & (unit >= 0) ? 100 * unit + '%' : unit + 'px') : void 0 } else if (unit.includes('px')) { return normalizeUnitToStyle(parseFloat(unit)) } else if (unit.includes('%')) { return normalizeUnitToStyle(parseFloat(unit) / 100) } else { return unit } }