@whitesev/pops
Version:
弹窗库
391 lines (383 loc) • 10.5 kB
text/typescript
import { PopsCore } from "../Core";
import type { PopsUtilsOwnObject } from "../types/main";
import { popsDOMUtils } from "./PopsDOMUtils";
import AnyTouch from "any-touch";
class PopsUtils {
/**
* 判断是否是window,例如window、self、globalThis
* @param target
*/
isWin(target: any) {
if (typeof target !== "object") {
return false;
}
if (target instanceof Node) {
return false;
}
if (target === globalThis) {
return true;
}
if (target === window) {
return true;
}
if (target === self) {
return true;
}
if (target === PopsCore.globalThis) {
return true;
}
if (target === PopsCore.window) {
return true;
}
if (target === PopsCore.self) {
return true;
}
if (
typeof (unsafeWindow as any) !== "undefined" &&
target === (unsafeWindow as any)
) {
return true;
}
if (target?.Math?.toString() !== "[object Math]") {
return false;
}
return true;
}
/**
* 判断对象是否是元素
* @param target
* @returns
* + true 是元素
* + false 不是元素
* @example
* Utils.isDOM(document.querySelector("a"))
* > true
*/
isDOM(target: any): boolean;
isDOM(target: any): boolean {
return target instanceof Node;
}
/**
* 删除对象上的属性
* @param target
* @param propName
*/
delete(target: any, propName: any) {
if (typeof Reflect === "object" && Reflect.deleteProperty) {
Reflect.deleteProperty(target, propName);
} else {
delete target[propName];
}
}
/**
* JSON数据从源端替换到目标端中,如果目标端存在该数据则替换,不添加,返回结果为目标端替换完毕的结果
* @param target 目标数据
* @param source 源数据
* @param isAdd 是否可以追加键,默认false
* @example
* Utils.assign({"1":1,"2":{"3":3}}, {"2":{"3":4}});
* >
* {
"1": 1,
"2": {
"3": 4
}
}
*/
assign<T1, T2 extends object, T3 extends boolean>(
target: T1,
source: T2,
isAdd?: T3
): T3 extends true ? T1 & T2 : T1;
assign(target = {}, source = {}, isAdd = false) {
let UtilsContext = this;
if (source == null) {
return target;
}
if (target == null) {
target = {};
}
if (Array.isArray(source)) {
let canTraverse = source.filter((item) => {
return typeof item === "object";
});
if (!canTraverse.length) {
return source;
}
}
if (isAdd) {
for (const sourceKeyName in source) {
const targetKeyName = sourceKeyName;
let targetValue = (target as any)[targetKeyName];
let sourceValue = (source as any)[sourceKeyName];
if (
typeof sourceValue === "object" &&
sourceValue != null &&
sourceKeyName in target &&
!UtilsContext.isDOM(sourceValue)
) {
/* 源端的值是object类型,且不是元素节点 */
(target as any)[sourceKeyName] = UtilsContext.assign(
targetValue,
sourceValue,
isAdd
);
continue;
}
(target as any)[sourceKeyName] = sourceValue;
}
} else {
for (const targetKeyName in target) {
if (targetKeyName in source) {
// @ts-ignore
let targetValue = target[targetKeyName];
// @ts-ignore
let sourceValue = source[targetKeyName];
if (
typeof sourceValue === "object" &&
sourceValue != null &&
!UtilsContext.isDOM(sourceValue) &&
Object.keys(sourceValue).length
) {
/* 源端的值是object类型,且不是元素节点 */
// @ts-ignore
target[targetKeyName] = UtilsContext.assign(
targetValue,
sourceValue,
isAdd
);
continue;
}
/* 直接赋值 */
// @ts-ignore
target[targetKeyName] = sourceValue;
}
}
}
return target;
}
/**
* 生成uuid
*/
getRandomGUID() {
if (typeof PopsCore.globalThis?.crypto?.randomUUID === "function") {
return PopsCore.globalThis.crypto.randomUUID();
} else {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
/[xy]/g,
function (charStr) {
var randomValue = (Math.random() * 16) | 0,
randomCharValue =
charStr === "x" ? randomValue : (randomValue & 0x3) | 0x8;
return randomCharValue.toString(16);
}
);
}
}
/**
* 字符串转HTMLElement
* @param elementString
* @returns
*/
parseTextToDOM<R extends HTMLElement>(elementString: string): R {
/* 去除前后的换行和空格 */
elementString = elementString
.replace(/^[\n|\s]*/g, "")
.replace(/[\n|\s]*$/g, "");
let targetElement = popsDOMUtils.createElement("div", {
innerHTML: elementString,
});
return targetElement.firstChild as any as R;
}
/**
* 判断元素/页面中是否包含该元素
* @param target 需要判断的元素
* @param context 默认为body
*/
contains(target: any): boolean;
contains(context: any, target?: any): boolean;
contains(context: any, target?: any): boolean {
if (arguments.length === 1) {
// 只判断该页面是否存在该元素
return this.contains(
PopsCore.document.body || PopsCore.document.documentElement,
arguments[0]
);
} else {
if (target == null) {
return false;
}
if (typeof (target as any)[Symbol.iterator] === "function") {
// 可遍历的数组
let flag = true;
for (const targetNode of target as any) {
if (!context.contains(targetNode)) {
flag = false;
break;
}
}
return flag;
} else {
return context.contains(target as HTMLElement);
}
}
}
/**
* 获取格式化后的时间
* @param text (可选)需要格式化的字符串或者时间戳,默认:new Date()
* @param formatType (可选)格式化成的显示类型,默认:yyyy-MM-dd HH:mm:ss
* + yyyy 年
* + MM 月
* + dd 天
* + HH 时 (24小时制)
* + hh 时 (12小时制)
* + mm 分
* + ss 秒
* @returns {string} 返回格式化后的时间
* @example
* Utils.formatTime("2022-08-21 23:59:00","HH:mm:ss");
* > '23:59:00'
* @example
* Utils.formatTime(1899187424988,"HH:mm:ss");
* > '15:10:13'
* @example
* Utils.formatTime()
* > '2023-1-1 00:00:00'
**/
formatTime(text?: string | number | Date, formatType?: string): string;
/**
* 获取格式化后的时间
* @param text (可选)需要格式化的字符串或者时间戳,默认:new Date()
* @param formatType (可选)格式化成的显示类型,默认:yyyy-MM-dd HH:mm:ss
* + yyyy 年
* + MM 月
* + dd 天
* + HH 时 (24小时制)
* + hh 时 (12小时制)
* + mm 分
* + ss 秒
* @returns {string} 返回格式化后的时间
* @example
* Utils.formatTime("2022-08-21 23:59:00","HH:mm:ss");
* > '23:59:00'
* @example
* Utils.formatTime(1899187424988,"HH:mm:ss");
* > '15:10:13'
* @example
* Utils.formatTime()
* > '2023-1-1 00:00:00'
**/
formatTime(
text?: string | number | Date,
formatType?:
| "yyyy-MM-dd HH:mm:ss"
| "yyyy/MM/dd HH:mm:ss"
| "yyyy_MM_dd_HH_mm_ss"
| "yyyy年MM月dd日 HH时mm分ss秒"
| "yyyy年MM月dd日 hh:mm:ss"
| "yyyy年MM月dd日 HH:mm:ss"
| "yyyy-MM-dd"
| "yyyyMMdd"
| "HH:mm:ss"
): string;
formatTime(text = new Date(), formatType = "yyyy-MM-dd HH:mm:ss") {
let time = text == null ? new Date() : new Date(text);
/**
* 校验时间补0
* @param timeNum
* @returns
*/
function checkTime(timeNum: number) {
if (timeNum < 10) return "0" + timeNum;
return timeNum;
}
/**
* 时间制修改 24小时制转12小时制
* @param hourNum 小时
* @returns
*/
function timeSystemChange(hourNum: number) {
return hourNum > 12 ? hourNum - 12 : hourNum;
}
let timeRegexp = {
yyyy: time.getFullYear(),
/* 年 */
MM: checkTime(time.getMonth() + 1),
/* 月 */
dd: checkTime(time.getDate()),
/* 日 */
HH: checkTime(time.getHours()),
/* 时 (24小时制) */
hh: checkTime(timeSystemChange(time.getHours())),
/* 时 (12小时制) */
mm: checkTime(time.getMinutes()),
/* 分 */
ss: checkTime(time.getSeconds()),
/* 秒 */
};
Object.keys(timeRegexp).forEach(function (key) {
let replaecRegexp = new RegExp(key, "g");
formatType = formatType.replace(replaecRegexp, (timeRegexp as any)[key]);
});
return formatType;
}
/**
* 格式化byte为KB、MB、GB、TB、PB、EB、ZB、YB、BB、NB、DB
* @param byteSize 字节
* @param addType (可选)是否添加单位
* + true (默认) 添加单位
* + false 不添加单位
* @returns
* + {string} 当addType为true时,且保留小数点末尾2位
* + {number} 当addType为false时,且保留小数点末尾2位
* @example
* Utils.formatByteToSize("812304");
* > '793.27KB'
* @example
* Utils.formatByteToSize("812304",false);
* > 793.27
**/
formatByteToSize<T extends boolean>(
byteSize: number | string,
addType?: T
): T extends true ? string : number;
formatByteToSize(byteSize: number | string, addType = true) {
byteSize = parseInt(byteSize.toString());
if (isNaN(byteSize)) {
throw new Error("Utils.formatByteToSize 参数 byteSize 格式不正确");
}
let result = 0;
let resultType = "KB";
let sizeData: PopsUtilsOwnObject<number> = {};
sizeData.B = 1;
sizeData.KB = 1024;
sizeData.MB = sizeData.KB * sizeData.KB;
sizeData.GB = sizeData.MB * sizeData.KB;
sizeData.TB = sizeData.GB * sizeData.KB;
sizeData.PB = sizeData.TB * sizeData.KB;
sizeData.EB = sizeData.PB * sizeData.KB;
sizeData.ZB = sizeData.EB * sizeData.KB;
sizeData.YB = sizeData.ZB * sizeData.KB;
sizeData.BB = sizeData.YB * sizeData.KB;
sizeData.NB = sizeData.BB * sizeData.KB;
sizeData.DB = sizeData.NB * sizeData.KB;
for (let key in sizeData) {
result = byteSize / (sizeData as any)[key];
resultType = key;
if (sizeData.KB >= result) {
break;
}
}
new Date();
result = result.toFixed(2) as any;
result = addType
? result + resultType.toString()
: (parseFloat(result.toString()) as any);
return result;
}
AnyTouch = () => {
return AnyTouch;
};
}
const popsUtils = new PopsUtils();
export { popsUtils };