import { PopsCommonCSSClassName } from "../config/CommonCSSClassName"; import { PopsInstData } from "../PopsInst"; import type { PopsInstStoreType } from "../types/main"; import { popsDOMUtils } from "./PopsDOMUtils"; import { popsUtils } from "./PopsUtils"; export const PopsInstanceUtils = { /** * 获取pops所有弹窗中的最大的z-index * @param deviation */ getPopsMaxZIndex(deviation: number = 10) { deviation = Number.isNaN(deviation) ? 10 : deviation; // 最大值 2147483647 // const browserMaxZIndex = Math.pow(2, 31) - 1; // 比较值 2000000000 const maxZIndex = 2 * Math.pow(10, 9); // 当前页面最大的z-index let zIndex = 0; // 当前的最大z-index的元素,调试使用 let maxZIndexNode = null as HTMLElement | null; Object.keys(PopsInstData).forEach((instKeyName) => { const instData = PopsInstData[instKeyName as PopsInstStoreType]; for (let index = 0; index < instData.length; index++) { const inst = instData[index]; // 不对position为static和display为none的元素进行获取它们的z-index const $elList = [inst.$anim, inst.$pops, inst.$mask].filter((it) => it instanceof HTMLElement); const maxNodeZIndexInfo = popsUtils.getMaxZIndexNodeInfoFromPoint($elList)[0]; if (maxNodeZIndexInfo) { const nodeZIndex = maxNodeZIndexInfo.zIndex; if (nodeZIndex > zIndex) { zIndex = nodeZIndex; maxZIndexNode = maxNodeZIndexInfo.node! || maxNodeZIndexInfo.positionNode!; } } } }); zIndex += deviation; const isOverMaxZIndex = zIndex >= maxZIndex; if (isOverMaxZIndex) { // 超出z-index最大值 zIndex = maxZIndex; } return { zIndex: zIndex, animElement: maxZIndexNode, isOverMaxZIndex }; }, /** * 排序数组 * @param getBeforeValueFun * @param getAfterValueFun * @param sortByDesc 排序是否降序,默认降序 */ sortElementListByProperty( getBeforeValueFun: (value: T) => R, getAfterValueFun: (value: T) => R, sortByDesc = true ) { if (typeof sortByDesc !== "boolean") { throw new TypeError("参数 sortByDesc 必须为boolean类型"); } if (getBeforeValueFun == null || getAfterValueFun == null) { throw new Error("获取前面的值或后面的值的方法不能为空"); } return function (after_obj: T, before_obj: T) { const beforeValue = getBeforeValueFun(before_obj); // 前 const afterValue = getAfterValueFun(after_obj); // 后 if (sortByDesc) { if (afterValue > beforeValue) { return -1; } else if (afterValue < beforeValue) { return 1; } else { return 0; } } else { if (afterValue < beforeValue) { return -1; } else if (afterValue > beforeValue) { return 1; } else { return 0; } } }; }, /** * 是否是隐藏状态 * * 检测以下项: * * + `display`: none * + `visibility`: hidden * + `opacity`: 0 * + `使用了pops的自定义的隐藏class类` * @param $el 需要检测的元素 */ isHide($el: Element) { let flag = false; if ( popsDOMUtils.containsClassName($el, PopsCommonCSSClassName.hide) || popsDOMUtils.containsClassName($el, PopsCommonCSSClassName.hideImportant) ) { flag = true; } else { if ($el instanceof HTMLElement) { const style = $el.style; flag = style.display.includes("none") || style.visibility.includes("hidden") || style.opacity !== "0"; } if (!flag) { const style = globalThis.getComputedStyle($el); flag = style.display.includes("none") || style.visibility.includes("hidden") || style.opacity !== "0"; } } return flag; }, /** * 判断元素是否是在`.pops`内 * @param $el 目标元素 */ isNodeInPopsNode($el: Element) { return !!($el.closest(".pops") || $el.matches(".pops")); }, /** * 判断是否是`.pops-anim`元素 * @param $el 目标元素 */ isAnimNode($el: Element) { return !!( $el?.localName?.toLowerCase() === "div" && $el.className && $el.className === "pops-anim" && $el.hasAttribute("anim") ); }, };