/**
* @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 固定到顶部(吸顶)
* @param {*} strToJson JSON.parse解析报错处理方案
*/
数据类型检查
/**
* @description: JS 数据类型检查
* @param {*} content 检测值
* @param {*} Type 期待类型
* @return {*} Boolean
*/
export function checkDataType(content, Type) {
return Object.prototype.toString.call(content) === `[object ${Type}]`;
}
checkDataType('hello','string') //true
生成随机数,支持随机小数
/**
* @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);
}
randomNum(10,30,2) //20.75
简单数组去重
/**
* @description 简单数组去重
* @param {*} arg 数组
* @returns Array
*/
export function easyArrRepetition(...arg) {
return [...new Set([...arg].flat(Infinity))];
}
const arr1 = [1,2,3],arr2 = [2,3,4]
easyArrRepetition(arr1, arr2) //[ 1, 2, 3, 4 ]
复杂数组去重
/**
* @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;
}, []);
}
const arr1 = [
{ name: '张三', id: 1 },
{ name: '李四', id: 2 },
{ name: '王五', id: 3 }
]
const arr2 = [
{ name: '张三', id: 1 },
{ name: '李四', id: 2 },
{ name: '赵六', id: 5 }
]
complexArrRepetition('id', arr1, arr2)
/*
[
{ name: '张三', id: 1 },
{ name: '李四', id: 2 },
{ name: '王五', id: 3 },
{ name: '赵六', id: 5 }
]
*/
封装 Promise.all 遇到 reject 后,直接返回问题
/**
* @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);
})
});
}
const promiseArr = [
Promise.resolve('resolve'),
Promise.reject('reject'),
'hello word',
{ name: '张三' }
]
promiseAll(promiseArr).then(res => {
console.log(res);
//[ 'resolve', 'reject', 'hello word', { name: '张三' } ]
})
秒级时间戳、毫秒级时间戳、日期对象 格式化时间
/**
* @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;
}
dateFormat(new Date(), 'yyyy-MM-dd hh') // 2020-11-24 15
验证手机号格式是否正确
}
/**
* @description 验证手机号格式是否正确
* @param phone 手机号
* @returns boolean
*/
export function checkMobile(phone) {
let reg = /^1\d{10}$/;
return !!reg.test(phone);
}
checkMobile(13113113133) // true
验证邮箱格式是否正确
}
/**
* @description 验证邮箱格式是否正确
* @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);
}
checkEmail('test@163.com') //true
验证密码格式是否正确
}
/**
* @description 验证密码格式是否正确 (必须为 6-20 个字符,而且同时包含字母和数字)
* @param password 密码
* @returns boolean
*/
export function checkPassword(password) {
let reg = /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$/;
return !!reg.test(password);
}
checkPassword('test123') //true
生成n位随机数
/**
* @description 生成n位随机
* @param n 随机数位数
* @returns string
*/
export function createRandomNum(n) {
let rnd = "";
for (let i = 0; i < n; i++) {
rnd += Math.floor(Math.random() * 10);
}
return parseInt(rnd, 10);
}
createRandomNum(12) //506177665520
保留2位小数
/**
* @description 保留2位小数
* @param x 0.00格式
* @returns string
*/
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;
}
toDecimal2(138) //138.00
生成uuid
/**
* @description 生成uuid
* @returns string
*/
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;
}
createUuid() //48b4a373-8ad5-460f-ba2b-77561a43c413
判断运行环境
/**
* @description 判断运行环境
* @returns object
*/
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)),
};
}
browserInfo()
//{"isAndroid":false,"isIphone":true,"isIpad":false,"isWeixin":false,"isAli":false,"isPhone":true}
判断运行设备
/**
* @description 判断运行设备
* @returns string
*/
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";
}
}
detectOS() // mac
深拷贝
/**
* @description: 深拷贝
* @param {*} arg
* @return {*} object
*/
export function deepClone(arg) {
return arg && JSON.parse(JSON.stringify(arg))
}
deepClone() // object
格式化金钱
/**
* @description: 格式化金钱
* @param {*} num
* @return {*} string
*/
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, ",");
}
thousandNum(1453257.45) //1,453,257.45
生成随机ID
/**
* @description: 生成随机ID
* @param {*} len
* @return {*} string
*/
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);
}
randomId(8) // fxh4e43z
生成随机HEX色值
/**
* @description: 生成随机HEX色值
* @return {*} string
*/
export function randomColor() {
return "#" + Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, "0");
}
randomColor() // #f313f1
懒加载
/**
* @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);
}
JSON.parse解析报错处理方案
/**
* @description: string to json
* @param {*} jsonStr Json字符串
* @return {*}
*/
export function strToJson(jsonStr) {
let obj = {};
if (
jsonStr &&
Object.prototype.toString.call(jsonStr) == "[object String]" &&
jsonStr != "null"
) {
jsonStr = jsonStr.replace(/\r/g, '\\r')
jsonStr = jsonStr.replace(/\n/g, '\\n')
jsonStr = jsonStr.replace(/\t/g, '\\t')
jsonStr = jsonStr.replace(/\\/g, '\\\\')
jsonStr = jsonStr.replace(/\'/g, ''')
jsonStr = jsonStr.replace(/ /g, ' ')
jsonStr = jsonStr.replace(/</g, '$lt;')
jsonStr = jsonStr.replace(/>/g, '$gt;')
obj = JSON.parse(jsonStr);
}
return obj;
}
后续会继续在这篇文章上总结JS开发技巧....
如果觉得对你有帮助,请动用你的小手点点赞,感谢!