UNPKG

vitepress-theme-base-teek

Version:
255 lines (222 loc) 6.31 kB
/** * 是否为合法的 URL 前缀 */ export const isExternal = (path: string) => /^(http?:|https?:|mailto:|tel:)/.test(path); /** * 是否是有效的 URL */ export const isValidURL = (url: string) => { try { new URL(url); return true; } catch { return false; } }; /** * 判断数据类型 * @param {Any} val 需要判断类型的数据 * @return string */ export const isType = (val: any) => { if (val === null) return "null"; if (typeof val !== "object") return typeof val; else return Object.prototype.toString.call(val).slice(8, -1).toLocaleLowerCase(); }; /** * 判断值是否未某个类型 */ export const is = (val: unknown, type: string) => { return Object.prototype.toString.call(val) === `[object ${type}]`; }; /** * 是否为函数 */ export const isFunction = <T = Function>(val: unknown): val is T => { return is(val, "Function"); }; /** * 是否已定义 */ export const isDef = <T = unknown>(val?: T): val is T => { return typeof val !== "undefined"; }; /** * 是否为未定义 */ export const isUnDef = <T = unknown>(val?: T): val is T => { return !isDef(val); }; /** * 是否为对象 */ export const isObject = (val: any): val is Record<any, any> => { return val !== null && is(val, "Object"); }; /** * 是否为时间 */ export const isDate = (val: unknown): val is Date => { return is(val, "Date"); }; /** * 是否是有效的数字(包含正负整数,0 以及正负浮点数) */ export const isNumber = (val: unknown): val is number => { const regPos = /^\d+(\.\d+)?$/; // 非负浮点数 const regNeg = /^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$/; // 负浮点数 if (regPos.test(val as string) || regNeg.test(val as string)) { return true; } else { return false; } }; /** * 是否为字符串数字 */ export const isStringNumber = (val: string): boolean => { if (!isString(val)) return false; return !Number.isNaN(Number(val)); }; /** * 是否为 AsyncFunction */ export const isAsyncFunction = <T = any>(val: unknown): val is Promise<T> => { return is(val, "AsyncFunction"); }; /** * 是否为 promise */ export const isPromise = <T = any>(val: unknown): val is Promise<T> => { return is(val, "Promise") && isObject(val) && isFunction(val.then) && isFunction(val.catch); }; /** * 是否为字符串 */ export const isString = (val: unknown): val is string => { return is(val, "String"); }; /** * 是否为boolean类型 */ export const isBoolean = (val: unknown): val is boolean => { return is(val, "Boolean"); }; /** * 是否为数组 */ export const isArray = (arg: any) => { if (typeof Array.isArray === "undefined") { return Object.prototype.toString.call(arg) === "[object Array]"; } return Array.isArray(arg); }; /** * 是否客户端 */ export const isClient = typeof window !== "undefined" && typeof document !== "undefined"; /** * 是否为服务器 */ export const isServer = !isClient; /** * 是否在浏览器中 */ export const inBrowser = isClient; /** * 是否为元素节点 */ export const isElement = (val: unknown): val is Element => { if (typeof Element === "undefined") return false; return val instanceof Element; }; // 是否为图片节点 export const isImageDom = (o: Element) => { return o && ["IMAGE", "IMG"].includes(o.tagName); }; /** * 是否为 null */ export const isNull = (val: unknown): val is null => { return val === null; }; /** * 是否为 null 且未定义 */ export const isNullAndUnDef = (val: unknown): val is null | undefined => { return isUnDef(val) && isNull(val); }; /** * 是否为 null 或未定义 */ export const isNullOrUnDef = (val: unknown): val is null | undefined => { return isUnDef(val) || isNull(val); }; /** * 是否为手机号 */ export const isPhone = (val: string) => { return /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/.test(val); }; /** * 是否是图片链接 */ export const isImgPath = (path: string): boolean => { return /(https?:\/\/|data:image\/).*?\.(png|jpg|jpeg|gif|svg|webp|ico)/gi.test(path); }; export const isIOS = () => { return ( isClient && window?.navigator?.userAgent && (/iP(?:ad|hone|od)/.test(window.navigator.userAgent) || (window?.navigator?.maxTouchPoints > 2 && /iPad|Macintosh/.test(window?.navigator.userAgent))) ); }; /** * 是否为空值项(包含数组、对象判断) * * @param checkFull 是否检查数组、对象是否为空。默认 true */ export const isEmpty = (val: any, checkFull = true): boolean => { // NaN 的检查 if (isNumber(val) && isNaN(val)) return true; // 检查空字符串、null 和 undefined if (val === "" || val === null || val === undefined) return true; if (!checkFull) return false; // 检查是不是数组并且长度为 0 if (isArray(val) && val.length === 0) return true; // 检查是不是对象并且没有自身可枚举属性 if (isObject(val) && Object.keys(val).length === 0) return true; // 如果以上都不是,则不为空 return false; }; /** * 确定目标元素是否可聚焦 * * @param element HTML 元素 */ export const isFocusable = (element: HTMLElement): boolean => { if (element.tabIndex > 0 || (element.tabIndex === 0 && element.getAttribute("tabIndex") !== null)) { return true; } if (element.tabIndex < 0 || element.hasAttribute("disabled") || element.getAttribute("aria-disabled") === "true") { return false; } switch (element.nodeName) { case "A": { // casting current element to Specific HTMLElement in order to be more type precise return !!(element as HTMLAnchorElement).href && (element as HTMLAnchorElement).rel !== "ignore"; } case "INPUT": { return !((element as HTMLInputElement).type === "hidden" || (element as HTMLInputElement).type === "file"); } case "BUTTON": case "SELECT": case "TEXTAREA": { return true; } default: { return false; } } };