JS常用工具库

1,792 阅读3分钟

整点JS工具函数到时候用的时候直接复制粘贴

工作中总是会遇到重复的工作内容,写多了每次写都会很腻。于是就打算写一个工具函数,把大部分写的内容抽离出来就是自己的工具库了。部分是自己写的,大部分是自己从别人哪里借鉴的!

1.时间格式化

const formatTime = function(timestamp, nos = 1, bindf = '-') {
	if (!timestamp) {
		return '--'
	}
	if ((timestamp + "").includes('Invalid Date')) {
		return '--'
	}
	var date = new Date(timestamp)
	var strLen = timestamp.toString().length
	//判断时间戳是否不足13位,不足时低位补0,即乘以10的所差位数次方
	if (strLen < 13) {
		var sub = 13 - strLen
		sub = Math.pow(10, sub) //计算10的n次方
		date = new Date(timestamp * sub)
	}
	var y = date.getFullYear()
	var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1)
	var d = (date.getDate() < 10 ? '0' + (date.getDate()) : date.getDate())
	var h = (date.getHours() < 10 ? '0' + (date.getHours()) : date.getHours())
	var m = (date.getMinutes() < 10 ? '0' + (date.getMinutes()) : date.getMinutes())
	var s = (date.getSeconds() < 10 ? '0' + (date.getSeconds()) : date.getSeconds())
	if (nos == 1) {
		return y + bindf + M + bindf + d + ' ' + h + ':' + m + ':' + s
	} else if (nos == 2) {
		return y + bindf + M + bindf + d
	} else if (nos == 3) {
		return M + bindf + d
	} else if (nos == 4) {
		return h + ':' + m + ':' + s
	} else if (nos == 5) {
		return y + bindf + M + bindf + d + ' ' + h + ':' + m
	} else if (nos == 6) {
		return M + bindf + d + ' ' + h + ':' + m + ':' + s
	} else if (nos == 7) {
		return M + bindf + d + ' ' + h + ':' + m
	} else if (nos == 8) {
		return d + '天' + h + '小时' + m + '分钟' + s + '秒'
	}
}

2.解析url参数

function GetUrlParam(urlStr) {
	// ?a=1&b=2&c=3 ==> {a: "1", b: "2", c: "3"}
	let url = urlStr.toString();
	let arrObj = url.split("?");
	let params = Object.create(null)
	if (arrObj.length > 1) {
		arrObj = arrObj[1].split("&");
		arrObj.forEach(item => {
			item = item.split("=");
			params[item[0]] = item[1]
		})
	}
	return params;
}

3.指定范围随机数

function RandomNum(min, max) {
	return Math.floor(Math.random() * (max - min + 1)) + min;
}

4.深拷贝

function deepClone(obj, cache = new WeakMap()) {
	if (typeof obj !== 'object') return obj // 普通类型,直接返回
	if (obj === null) return obj
	if (cache.get(obj)) return cache.get(obj) // 防止循环引用,程序进入死循环
	if (obj instanceof Date) return new Date(obj)
	if (obj instanceof RegExp) return new RegExp(obj)
	// 找到所属原型上的constructor,所属原型上的constructor指向当前对象的构造函数
	let cloneObj = new obj.constructor()
	cache.set(obj, cloneObj) // 缓存拷贝的对象,用于处理循环引用的情况
	for (let key in obj) {
		if (obj.hasOwnProperty(key)) {
			cloneObj[key] = deepClone(obj[key], cache) // 递归拷贝
		}
	}
	return cloneObj
}

5.字符串空格处理

function trim(str, type = 1) {
	/* 去除空格类型 1-所有空格  2-前后空格  3-前空格 4-后空格 默认为1 */
	if (type && type !== 1 && type !== 2 && type !== 3 && type !== 4) return;
	switch (type) {
		case 1:
			return str.replace(/\s/g, "");
		case 2:
			return str.replace(/(^\s)|(\s*$)/g, "");
		case 3:
			return str.replace(/(^\s)/g, "");
		case 4:
			return str.replace(/(\s$)/g, "");
		default:
			return str;
	}
}

6.检测银行卡号

const checkBankNumber = function(bankno) {
	var lastNum = bankno.substr(bankno.length - 1, 1); //取出最后一位(与luhm进行比较)
	var first15Num = bankno.substr(0, bankno.length - 1); //前15或18位
	var newArr = [];
	for (var i = first15Num.length - 1; i > -1; i--) { //前15或18位倒序存进数组
		newArr.push(first15Num.substr(i, 1));
	}
	var arrJiShu = []; //奇数位*2的积 <9
	var arrJiShu2 = []; //奇数位*2的积 >9
	var arrOuShu = []; //偶数位数组
	for (var j = 0; j < newArr.length; j++) {
		if ((j + 1) % 2 == 1) { //奇数位
			if (parseInt(newArr[j]) * 2 < 9)
				arrJiShu.push(parseInt(newArr[j]) * 2);
			else
				arrJiShu2.push(parseInt(newArr[j]) * 2);
		} else //偶数位
			arrOuShu.push(newArr[j]);
	}
	var jishu_child1 = []; //奇数位*2 >9 的分割之后的数组个位数
	var jishu_child2 = []; //奇数位*2 >9 的分割之后的数组十位数
	for (var h = 0; h < arrJiShu2.length; h++) {
		jishu_child1.push(parseInt(arrJiShu2[h]) % 10);
		jishu_child2.push(parseInt(arrJiShu2[h]) / 10);
	}
	var sumJiShu = 0; //奇数位*2 < 9 的数组之和
	var sumOuShu = 0; //偶数位数组之和
	var sumJiShuChild1 = 0; //奇数位*2 >9 的分割之后的数组个位数之和
	var sumJiShuChild2 = 0; //奇数位*2 >9 的分割之后的数组十位数之和
	var sumTotal = 0;
	for (var m = 0; m < arrJiShu.length; m++) {
		sumJiShu = sumJiShu + parseInt(arrJiShu[m]);
	}
	for (var n = 0; n < arrOuShu.length; n++) {
		sumOuShu = sumOuShu + parseInt(arrOuShu[n]);
	}
	for (var p = 0; p < jishu_child1.length; p++) {
		sumJiShuChild1 = sumJiShuChild1 + parseInt(jishu_child1[p]);
		sumJiShuChild2 = sumJiShuChild2 + parseInt(jishu_child2[p]);
	}
	//计算总和
	sumTotal = parseInt(sumJiShu) + parseInt(sumOuShu) + parseInt(sumJiShuChild1) + parseInt(sumJiShuChild2);
	//计算Luhm值
	var k = parseInt(sumTotal) % 10 == 0 ? 10 : parseInt(sumTotal) % 10;
	var luhm = 10 - k;
	if (lastNum == luhm) {
		return true;
	} else {
		return false;
	}
}

7.检测身份证号码

const checkIdCard = function(str) {
	var reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
	return reg.test(str);
}

8.检测手机号码

const checkPhone = function(val) {
	return (/^1[3-9]\d{9}$/.test(val))
}

9.防抖 女盆友打你的时候希望是防抖

function debounce(fn, delay) {
	let timer
	return function(...args) {
		if (timer) {
			clearTimeout(timer)
		}
		timer = setTimeout(() => {
			fn.apply(this, args)
		}, delay)
	}
}

10.节流 女朋友给你钱的时候希望是节流

function throttle(fn, delay) {
	let last = 0 // 上次触发时间
	return (...args) => {
		const now = Date.now()
		if (now - last > delay) {
			last = now
			fn.apply(this, args)
		}
	}
}

11.获取文件创建时间

function ShowFileData(filespec) {
	var fso, f, s;
	fso = new ActiveXObject("Scripting.FileSystemObject");
	f = fso.GetFile(filespec);
	var d = f.DateCreated;
	Cdate = new Date(d);
	d = f.DateLastModified;
	Mdate = new Date(d);
	d = f.DateLastAccessed;
	Adate = new Date(d);
	return "当前文件创建的时间" + Cdate.toLocaleString() +
		"\n当前文件的修改时间" + Mdate.toLocaleString() +
		"\n当前文件的访问时间" + Adate.toLocaleString();
}

12.RC4对称加密


function rc4(data, key) {
//  var ctext = rc4("啦啦啦123的吗", "65osdbsfidcxza");
//  var text = rc4(ctext, "65osdbsfidcxza");
    let seq = Array(256); //int
    let das = Array(data.length); //code of data
    for (let i = 0; i < 256; i++) {
        seq[i] = i;
        let j = (j + seq[i] + key.charCodeAt(i % key.length)) % 256;
        let temp = seq[i];
        seq[i] = seq[j];
        seq[j] = temp;
    }
    for (let i = 0; i < data.length; i++) {
        das[i] = data.charCodeAt(i)
    }
    for (let x = 0; x < das.length; x++) {
        let i = (i + 1) % 256;
        let j = (j + seq[i]) % 256;
        let temp = seq[i];
        seq[i] = seq[j];
        seq[j] = temp;
        let k = (seq[i] + (seq[j] % 256)) % 256;
        das[x] = String.fromCharCode(das[x] ^ seq[k]);
    }
    return das.join('');
}

13.扁平化数组转树结构 (导航栏常用)

// 扁平化数组转树结构
function arrayToTree(items) {
	const result = []; // 存放结果集
	const itemMap = {}; // 
	for (const item of items) {
		const id = item.id;
		const pid = item.pid;
		if (!itemMap[id]) {
			itemMap[id] = {
				children: [],
			}
		}
		itemMap[id] = {
			...item,
			children: itemMap[id]['children']
		}
		const treeItem = itemMap[id];
		if (pid === 0) {
			result.push(treeItem);
		} else {
			if (!itemMap[pid]) {
				itemMap[pid] = {
					children: [],
				}
			}
			itemMap[pid].children.push(treeItem)
		}
	}
	return result;
}

14.利用图片的url直接下载当前图片

function downloadIamge(imgsrc, name) {
    let image = new Image();
    // 解决跨域 Canvas 污染问题
    image.setAttribute("crossOrigin", "anonymous");
    image.onload = function() {
        let canvas = document.createElement("canvas");
        canvas.width = image.width;
        canvas.height = image.height;
        let context = canvas.getContext("2d");
        context.drawImage(image, 0, 0, image.width, image.height);
        let url = canvas.toDataURL("image/png"); //得到图片的base64编码数据
        let a = document.createElement("a"); // 生成一个a元素
        let event = new MouseEvent("click"); // 创建一个单击事件
        a.download = name || "photo"; // 设置图片名称
        a.href = url; // 将生成的URL设置为a.href属性
        a.dispatchEvent(event); // 触发a的单击事件
    }
    image.src = imgsrc;
}

15.随机颜色

const generateRandomHexColor = () => `#${Math.floor(Math.random() * 0xffffff).toString(16)}`

16.浏览器类型

export const isServer = typeof navigator === 'undefined';
/**
 * 是否是 Edge 浏览器
 * Mozilla/5.0 (Windows NT 10.0 Win64 x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36 Edge/17.17134
 */
export const isEdge = /edge/i.test(userAgent);
/**
 * 是否是 Chrome 浏览器
 * Mozilla/5.0 (Macintosh Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36
 */
export const isChrome = !isEdge && /chrome/i.test(userAgent);
/**
 * 是否是 Firefox 浏览器
 * Mozilla/5.0 (Macintosh Intel Mac OS X 10.13 rv:62.0) Gecko/20100101 Firefox/62.0
 */
export const isFirefox = /firefox/i.test(userAgent);
/**
 * 是否是 Safari 浏览器
 * Mozilla/5.0 (Macintosh Intel Mac OS X 10_13_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.1 Safari/605.1.15
 */
export const isSafari = !isEdge && !isChrome && /safari/i.test(userAgent);
/**
 * 是否是 手机浏览器
 */
export const isMobile = /mobile/i.test(userAgent);
/**
 * 是否是iOS系统
 */
export const isIos = /os [._\d]+ like mac os/i.test(userAgent);
/**
 * 是否是 安卓系统
 */
export const isAndroid = /android/i.test(userAgent);
/**
 * 是否是 Mac OS X 系统
 */
export const isMacos = !isIos && /mac os x/i.test(userAgent);
/**
 * 是否是 Windows 系统
 */
export const isWindows = /windows\s*(?:nt)?\s*[._\d]+/i.test(userAgent);
/**
 * 是否是 Ipad
 */
export const isIpad = /ipad/i.test(userAgent);

17.数组重新排序

const shuffle = (arr) => arr.sort(() => Math.random() - 0.5);

18.复制到剪切板

const copyToClipboard = (text) => navigator.clipboard && navigator.clipboard.writeText && navigator.clipboard.writeText(text)

19.检测暗色主题

const isDarkMode = () => window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;

20.滚动到顶部

  // 顶部
  const scrollToTop = (element) =>   
  element.scrollIntoView({ behavior"smooth", block"start" });
  // 底部
  const scrollToBottom = (element) =>   
  element.scrollIntoView({ behavior"smooth", block"end" });

21.检测元素是否在屏幕中

const callback = (entries) => {  
  entries.forEach((entry) => {  
    if (entry.isIntersecting) {  
      // `entry.target` is the dom element  
      console.log(`${entry.target.id} is visible`);  
    }  
  });  
};  

const options = {  
  threshold: 1.0,  
};  
const observer = new IntersectionObserver(callback, options);  
const btn = document.getElementById("btn");  
const bottomBtn = document.getElementById("bottom-btn");  
observer.observe(btn);  
observer.observe(bottomBtn);

22.隐藏元素

我们可以将元素的style.visibility设置为hidden,隐藏元素的可见性,但元素的空间仍然会被占用。如果设置元素的style.displaynone,会将元素从渲染流中删除。

const hideElement = (el, removeFromFlow = false) => {  
  removeFromFlow ? (el.style.display = 'none')  
  : (el.style.visibility = 'hidden')  
}

23.等待函数

JavaScript 提供了setTimeout函数,但是它并不返回 Promise 对象,所以我们没办法使用 async 作用在这个函数上,但是我们可以封装等待函数。

const wait = (ms) => new Promise((resolve)=> setTimeout(resolve, ms))

const asyncFn = async () => {
  await wait(1000)
  console.log('等待异步函数执行结束')
}

asyncFn()

参考掘金部分作者的文章

https://juejin.cn/post/7127278574033174542