@whitesev/pops
Version:
弹窗库,包含了alert、confirm、prompt、drawer、folder、loading、iframe、panel、tooltip、searchSuggestion、rightClickMenu组件
136 lines (133 loc) • 4.34 kB
text/typescript
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<T, R>(
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")
);
},
};