UNPKG

jsmethodutils

Version:

JS 常用方法总结

474 lines (461 loc) 11.7 kB
/** * @description: JS 常用方法封装 * @param {*} checkDataType 数据类型检查 * @param {*} randomNum 生成随机数,支持随机小数 * @param {*} easyArrRepetition 简单数组去重 * @param {*} complexArrRepetition 复杂数组去重 * @param {*} promiseAll 封装 Promise.all 遇到 reject 后,直接返回问题 * @param {*} dateFormat 秒级时间戳、毫秒级时间戳、日期对象 格式化时间 * @param {*} checkMobile 验证手机号格式是否正确 * @param {*} checkEmail 验证邮箱格式是否正确 * @param {*} checkPassword 验证密码格式是否正确 (必须为 6-20 个字符,而且同时包含字母和数字) * @param {*} createRandomNum 生成n位随机数 * @param {*} toDecimal2 保留2位小数 * @param {*} createUuid 生成uuid * @param {*} browserInfo 判断运行环境 * @param {*} detectOS 判断运行设备 * @param {*} throttle 节流(throttle) * @param {*} debounce 防抖(debounce) * @param {*} ThousandNum 格式化金钱 * @param {*} RandomId 生成随机ID * @param {*} RandomColor 生成随机HEX色值 * @param {*} lazyLoad 懒加载 * @param {*} loadMore 加载更多 * @param {*} fixedToHeader 固定到顶部(吸顶) */ /** * @description: JS 数据类型检查 * @param {*} content 检测值 * @param {*} Type 期待类型 * @return {*} Boolean */ export function checkDataType(content, Type) { return Object.prototype.toString.call(content) === `[object ${Type}]`; } /** * @description: 生成随机数,支持随机小数 * @param {*} min 最小值 * @param {*} max 最大值 * @param {*} point 几位小数,默认0 * @return {*} String */ export function randomNum(min = 0, max = 100, point = 0) { if (point && point > 0) { return (Math.random() * (max - min + 1) + min).toFixed(point); } return parseInt(Math.random() * (max - min + 1) + min); } /** * @description 简单数组去重 * @param {*} arg 数组 * @returns Array */ export function easyArrRepetition(...arg) { return [...new Set([...arg].flat(Infinity))]; } /** * @description 复杂数组去重 * @param key 根据key进行去重 * @param arg 数组 * @returns Array */ export function complexArrRepetition(key, ...arg) { if (!key || typeof key !== "string") return new Error("请传入正确的key值"); let arr = [...arg].flat(Infinity); let hash = {}; return arr.reduce((next, item) => { hash[item[key]] ? "" : (hash[item[key]] = true && next.push(item)); return next; }, []); } /** * @description 封装 Promise.all 遇到 reject 后,直接返回问题 * @param arg promise数组 * @returns Promise */ export function promiseAll(...arg) { return new Promise((resolve, reject) => { const promiseAll = [...arg] .flat(Infinity) .map( (item) => (Object.prototype.toString.call(item) === "[object Promise]" && item.catch((e) => e)) || item ); Promise.all(promiseAll) .then((res) => { resolve(res); }) .catch((err) => { reject(err); }); }); } /** * @description 秒级时间戳、毫秒级时间戳、日期对象 格式化时间 * @param date * @param fmt * @returns string */ export function dateFormat(date, fmt = "yyyy-MM-dd hh:mm:ss") { let type = Object.prototype.toString.call(date); if (type !== "[object Number]" && type !== "[object Date]") return; if (type === "[object Number]") date = new Date( Number(date).toString().length === 10 ? date * 1000 : date ); let o = { "M+": date.getMonth() + 1, //月份 "d+": date.getDate(), //日 "h+": date.getHours(), //小时 "m+": date.getMinutes(), //分 "s+": date.getSeconds(), //秒 "q+": Math.floor((date.getMonth() + 3) / 3), //季度 S: date.getMilliseconds(), //毫秒 }; if (/(y+)/.test(fmt)) fmt = fmt.replace( RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length) ); for (let k in o) if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace( RegExp.$1, RegExp.$1.length === 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length) ); return fmt; } /** * 验证手机号格式是否正确 * * @export * @param phone 手机号 * @returns boolean */ export function checkMobile(phone) { let reg = /^1\d{10}$/; return !!reg.test(phone); } /** * 验证邮箱格式是否正确 * * @export * @param email 邮箱 * @returns boolean */ export function checkEmail(email) { let reg = /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/; return !!reg.test(email); } /** * 验证密码格式是否正确 (必须为 6-20 个字符,而且同时包含字母和数字) * * @export * @param {number} password 密码 * @returns */ export function checkPassword(password) { let reg = /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$/; return !!reg.test(password); } /** * 生成随机数 * * @export * @param {number} n 随机数位数 * @returns */ export function createRandomNum(n) { let rnd = ""; for (let i = 0; i < n; i++) { rnd += Math.floor(Math.random() * 10); } return parseInt(rnd, 10); } /** * 保留2位小数 * * @export * @param {number} n 0.00格式 * @returns */ export function toDecimal2(x) { var f = parseFloat(x); if (isNaN(f)) { return false; } var f = Math.round(x * 100) / 100; var s = f.toString(); var rs = s.indexOf("."); if (rs < 0) { rs = s.length; s += "."; } while (s.length <= rs + 2) { s += "0"; } return s; } /** * @description 生成uuid */ export function createUuid() { let d = new Date().getTime(); let uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace( /[xy]/g, function (c) { let r = (d + Math.random() * 16) % 16 | 0; d = Math.floor(d / 16); return (c === "x" ? r : (r & 0x3) | 0x8).toString(16); } ); return uuid; } /** * @description 判断运行环境 */ export function browserInfo() { let ua = navigator.userAgent; return { isAndroid: Boolean(ua.match(/android/gi)), isIphone: Boolean(ua.match(/iphone|ipod/gi)), isIpad: Boolean(ua.match(/ipad/gi)), isWeixin: Boolean(ua.match(/MicroMessenger/gi)), isAli: Boolean(ua.match(/AlipayClient/gi)), isPhone: Boolean(/(iPhone|iPad|iPod|iOS|Android)/i.test(ua)), isApp: Boolean(/(zwwl-ios|zwwl-android)/i.test(ua)), }; } /** * @description 判断运行设备 */ export function detectOS() { const { platform } = navigator; const isWin = platform.toLowerCase() == "win32" || platform.toLowerCase() == "windows"; const hasLinux = platform.toLowerCase().includes("linux"); const hasTouch = "ontouchend" in document; if (isWin) return "Windows"; if (hasLinux) return "Pad"; if (hasTouch) { return "iPad"; } else { return "Mac"; } } /** * @description: 节流(throttle) * @param {*} fn * @param {*} delay * @return {*} */ export function throttle(fn, delay) { let valid = true; return function () { if (!valid) { return false; } valid = false; setTimeout(() => { fn && fn(); valid = true; }, delay); }; } /** * @description: 防抖(debounce) * @param {*} fn * @param {*} delay * @return {*} */ export function debounce(fn, delay) { let timer = null; return function () { if (timer) { clearTimeout(timer); } timer = setTimeout(fn, delay); }; } /** * @description: JS 深拷贝 * @param {*} arg * @return {*} */ export function deepClone(arg) { return arg && JSON.parse(JSON.stringify(arg)); } /** * @description: 格式化金钱 * @param {*} num * @return {*} */ export function thousandNum(num) { const types = ["string", "number"]; if (!types.includes(typeof num)) return new Error("传入参数格式错误!"); return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); } /** * @description: 生成随机ID * @param {*} len * @return {*} */ export function RandomId(len = 6) { const types = ["string", "number"]; if (!types.includes(typeof len)) return new Error("传入参数格式错误!"); return Math.random().toString(36).substr(3, len); } /** * @description: 生成随机HEX色值 * @return {*} */ export function RandomColor() { return ( "#" + Math.floor(Math.random() * 0xffffff) .toString(16) .padEnd(6, "0") ); } /** * @description: 懒加载 * @param {*} els 元素列表 * @param {*} preloadHeight 预加载高度 * @param {*} defaultSrc 渲染真实url标签属性名 * @return {*} */ export function lazyLoad( els = [], preloadHeight = 1000, defaultSrc = "data-src" ) { const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { // 目标元素出现在 root 可视区,返回 true const elTarget = entry.target; const src = elTarget.getAttribute(defaultSrc); src && elTarget.setAttribute("src", src); // 真正加载图片 observer.unobserve(elTarget); // 停止观察 } }); }, { rootMargin: `0px 0px ${preloadHeight}px 0px`, threshold: 0.1, //触发目标元素可见的时机 } ); Array.prototype.forEach.call(els, (el) => { observer.observe(el); // 开始观察 }); } /** * @description: 加载更多 * @param {*} cb 触底后的回调函数 * @param {*} el 触底元素 * @return {*} */ export function loadMore(cb, el) { if (!el || typeof el === "string") { throw new Error("请传入一个触底的dom元素"); return; } const observer = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { cb(); } }); }); observer.observe(el); } /** * @description: 固定到顶部(吸顶) * @param {*} fixedEl 顶部固定元素 * @param {*} observerEl 监听吸顶元素 * @param {*} className 固定到底部的className * @return {*} */ export function fixedToHeader(fixedEl, observerEl, className) { const observer = new IntersectionObserver((entries) => { entries.forEach((entry) => { if (!entry.isIntersecting) { className ? fixedEl.classList.add(className) : (fixedEl.style.cssText = "position: sticky; top: -1px; left: 0"); } else { className ? fixedEl.classList.remove(className) : (fixedEl.style.cssText = ""); } }); }); observer.observe(observerEl); } /** * @description: 非空判断 * @param {*} obj * @return {*} */ export function isNotEmpty(obj) { try { if (obj == null || obj == undefined) { return false; } //判断数字是否是NaN if (typeof obj === "number") { if (isNaN(obj)) { return false; } else { return true; } } //判断参数是否是布尔、函数、日期、正则,是则返回true if ( typeof obj === "boolean" || typeof obj === "function" || obj instanceof Date || obj instanceof RegExp ) { return true; } //判断参数是否是字符串,去空,如果长度为0则返回false if (typeof obj === "string") { if (obj.trim().length == 0) { return false; } else { return true; } } if (typeof obj === "object") { //判断参数是否是数组,数组为空则返回false if (obj instanceof Array) { if (obj.length == 0) { return false; } else { return true; } } //判断参数是否是对象,判断是否是空对象,是则返回false if (obj instanceof Object) { //判断对象属性个数 if (Object.getOwnPropertyNames(obj).length == 0) { return false; } else { return true; } } } } catch (e) { console.log(e); return false; } }