35个前端常用工具函数「值得收藏」
bigegpt 2024-09-27 00:33 3 浏览
作者: monkeysoft
转发链接:https://mp.weixin.qq.com/s/u1Ml5mKlj8Cobj6JLU0OBQ
前言
前一段时间小编也陆陆续续整理一批优质文章关于前端JS常用工具函数系列,根据粉丝们的反馈,的确工作效率提升了不少《细品269个JavaScript小函数,让你少加班熬夜(一)「值得收藏」 》,这次小编继续贡献。
工具函数篇
表单序列化
export const serialize = data => {
let list = []
Object.keys(data).forEach(ele => {
list.push(`${ele}=${data[ele]}`)
})
return list.join('&')
}
获取对象的类型
export const getObjType = obj => {
var toString = Object.prototype.toString
var map = {
'[object Boolean]': 'boolean',
'[object Number]': 'number',
'[object String]': 'string',
'[object Function]': 'function',
'[object Array]': 'array',
'[object Date]': 'date',
'[object RegExp]': 'regExp',
'[object Undefined]': 'undefined',
'[object Null]': 'null',
'[object Object]': 'object'
}
if (obj instanceof Element) {
return 'element'
}
return map[toString.call(obj)]
}
对象深拷贝
export const deepClone = data => {
var type = getObjType(data)
var obj
if (type === 'array') {
obj = []
} else if (type === 'object') {
obj = {}
} else {
// 不再具有下一层次
return data
}
if (type === 'array') {
for (var i = 0, len = data.length; i < len; i++) {
obj.push(deepClone(data[i]))
}
} else if (type === 'object') {
for (var key in data) {
obj[key] = deepClone(data[key])
}
}
return obj
}
判断路由是否相等
export const diff = (obj1, obj2) => {
delete obj1.close
var o1 = obj1 instanceof Object
var o2 = obj2 instanceof Object
if (!o1 || !o2) { /* 判断不是对象 */
return obj1 === obj2
}
if (Object.keys(obj1).length !== Object.keys(obj2).length) {
return false
// Object.keys() 返回一个由对象的自身可枚举属性(key值)组成的数组,例如:数组返回下标:let arr = ["a", "b", "c"];console.log(Object.keys(arr))->0,1,2;
}
for (var attr in obj1) {
var t1 = obj1[attr] instanceof Object
var t2 = obj2[attr] instanceof Object
if (t1 && t2) {
return diff(obj1[attr], obj2[attr])
} else if (obj1[attr] !== obj2[attr]) {
return false
}
}
return true
}
递归寻找子类的父类
export const findParent = (menu, id) => {
for (let i = 0; i < menu.length; i++) {
if (menu[i].children.length != 0) {
for (let j = 0; j < menu[i].children.length; j++) {
if (menu[i].children[j].id == id) {
return menu[i]
} else {
if (menu[i].children[j].children.length != 0) {
return findParent(menu[i].children[j].children, id)
}
}
}
}
}
}
动态插入css
export const loadStyle = url => {
const link = document.createElement('link')
link.type = 'text/css'
link.rel = 'stylesheet'
link.href = url
const head = document.getElementsByTagName('head')[0]
head.appendChild(link)
}
根据字典的value查找对应的index
export const findArray = (dic, value) => {
for (let i = 0; i < dic.length; i++) {
if (dic[i].value == value) {
return i
}
}
return -1
}
根据字典的value显示label
export const findByvalue = (dic, value) => {
let result = ''
if (validatenull(dic)) return value
if (typeof (value) === 'string' || typeof (value) === 'number' || typeof (value) === 'boolean') {
let index = 0
index = findArray(dic, value)
if (index != -1) {
result = dic[index].label
} else {
result = value
}
} else if (value instanceof Array) {
result = []
let index = 0
value.forEach(ele => {
index = findArray(dic, ele)
if (index != -1) {
result.push(dic[index].label)
} else {
result.push(value)
}
})
result = result.toString()
}
return result
}
生成随机len位数字
export const randomLenNum = (len, date) => {
let random = ''
random = Math.ceil(Math.random() * 100000000000000).toString().substr(0, len || 4)
if (date) random = random + Date.now()
return random
}
解决ie9不兼容placeholder问题
export function compatiblePlaceholder() {
if (!('placeholder' in document.createElement('input'))) {
// 将返回的nodeList对象转为数组
var nodes = Array.prototype.slice.call(document.querySelectorAll('[placeholder]'))
nodes.forEach(function (item, index) {
if (item.nextElementSibling) {
} else {
item.addEventListener('focus', function () {
this.nextSibling.style.display = 'none'
})
item.addEventListener('blur', function () {
if (!this.value) {
this.style.display = 'none'
this.nextSibling.style.display = 'inline'
}
})
var cloneNode = item.cloneNode()
// 如果[type='password']类型,则转为text
if (cloneNode.getAttribute('type').toLowerCase() === 'password') {
cloneNode.setAttribute('type', 'text')
}
cloneNode.setAttribute('value', cloneNode.getAttribute('placeholder'))
cloneNode.style.display = 'none'
item.insertAdjacentHTML('afterend', cloneNode.outerHTML)
item.nextSibling.addEventListener('focus', function () {
this.style.display = 'none'
this.previousSibling.style.display = 'inline'
this.previousSibling.focus()
})
if (!item.value) {
item.style.display = 'none'
item.nextSibling.style.display = 'inline'
}
}
})
}
}
精度丢失转换(乘法)
export function accMul(arg1, arg2) {
let m = 0, s1 = arg1.toString(), s2 = arg2.toString();
try { m += s1.split(".")[1].length } catch (e) { }
try { m += s2.split(".")[1].length } catch (e) { }
return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m)
}
节流函数
/**
* 节流函数,在一段时间内,回调函数只执行一次
* @param {Function} fun 需要节流的函数
* @param {number} delay 节流的时间,单位为毫秒
*/
export function throttle(fun, delay) {
let valid = true;
return function() {
let context = this;
let args = arguments;
if (!valid) {
return;
}
valid = false;
setTimeout(() => {
fn.apply(context, args);
valid = true;
}, delay);
}
}
防抖函数
/**
*防抖函数,多次触发事件后,事件处理函数只执行一次,并且是在触发操作结束时执行
*@param fn 事件触发的操作
*@param delay 多少毫秒内连续触发事件,不会执行
*@returns {Function}
*/
function debounce(fn, delay){
let timer = null; //借助闭包
return function(){
let context = this,
args = arguments;
timer && clearTimeout(timer);
timer = setTimeout(function(){
fn.apply(context, args);
},delay);
}
}
计算时间和当前时间的差值
export const spaceTime = function (atime) {
atime = atime.replace(/-/g, '/'); //IE出现兼容问题,带“-”格式的时间无法被new Date()转成时间格式,返回NaN.
let byTime = [365 * 24 * 60 * 60 * 1000, 24 * 60 * 60 * 1000, 60 * 60 * 1000, 60 * 1000, 1000];
let unit = ["年", "天", "小时", "分钟", "秒钟"];
var ct = new Date().getTime() - new Date(atime).getTime();
if (ct <= 1000) {
// return "时间数据出错!"
return "刚刚"
}
var sb = [];
for (var i = 0; i < byTime.length; i++) {
if (ct < byTime[i]) {
continue;
}
var temp = Math.floor(ct / byTime[i]);
ct = ct % byTime[i];
if (temp > 0) {
sb.push(temp + unit[i]);
}
/*一下控制最多输出几个时间单位:
一个时间单位如:N分钟前
两个时间单位如:M分钟N秒前
三个时间单位如:M年N分钟X秒前
以此类推
*/
if (sb.length >= 1) {
break;
}
}
return (sb.join("") + "前");
}
获取当前年月
export const getNowFormatDate = function() {
var date = new Date();
var seperator1 = "-";
var year = date.getFullYear();
var month = date.getMonth() + 1;
var strDate = date.getDate();
if (month >= 1 && month <= 9) {
month = "0" + month;
}
if (strDate >= 0 && strDate <= 9) {
strDate = "0" + strDate;
}
var currentdate = year + seperator1 + month;
return currentdate;
}
获取指定时间年月日
export const getFormatDate = function(data) {
var date = new Date(data);
var seperator1 = "-";
var year = date.getFullYear();
var month = date.getMonth() + 1;
var strDate = date.getDate();
if (month >= 1 && month <= 9) {
month = "0" + month;
}
if (strDate >= 0 && strDate <= 9) {
strDate = "0" + strDate;
}
var currentdate = year + seperator1 + month+strDate;
return currentdate;
}
获取距离当前时间多久的时间
/**
* 获取距离当前时间多久的时间
* @param type year年/month月/week周/day日
* @param number -为之前/+为之后
*/
export const getBeforAfterTime = function(type=null,number=0) {
var nowdate = new Date();
switch (type) {
case "day": //取number天前、后的时间
nowdate.setTime(nowdate.getTime() + (24 * 3600 * 1000) * number);
var y = nowdate.getFullYear();
var m = nowdate.getMonth() + 1;
var d = nowdate.getDate();
var retrundate = y + '/' + m + '/' + d;
break;
case "week": //取number周前、后的时间
nowdate.setTime(nowdate.getTime() + (7 * 24 * 3600 * 1000) * number);
var y = nowdate.getFullYear();
var m = nowdate.getMonth() + 1;
var d = nowdate.getDate();
var retrundate = y + '/' + m + '/' + d;
break;
case "month": //取number月前、后的时间
nowdate.setMonth(nowdate.getMonth() + number);
var y = nowdate.getFullYear();
var m = nowdate.getMonth() + 1;
var d = nowdate.getDate();
var retrundate = y + '/' + m + '/' + d;
break;
case "year": //取number年前、后的时间
nowdate.setFullYear(nowdate.getFullYear() + number);
var y = nowdate.getFullYear();
var m = nowdate.getMonth() + 1;
var d = nowdate.getDate();
var retrundate = y + '/' + m + '/' + d;
break;
default: //取当前时间
var y = nowdate.getFullYear();
var m = nowdate.getMonth() + 1;
var d = nowdate.getDate();
var retrundate = y + '/' + m + '/' + d;
}
return retrundate;
}
正则校验篇
邮箱
export function isEmail (s) {
return /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/.test(s)
}
手机号码
export function isMobile (s) {
return /^1[0-9]{10}$/.test(s)
}
电话号码
export function isPhone (s) {
return /^([0-9]{3,4}-)?[0-9]{7,8}$/.test(s)
}
匹配腾讯QQ号
export function isQQ (s) {
return /[1-9][0-9]{4,}/.test(s)
}
URL地址
export function isURL (s) {
return /^http[s]?:\/\/.*/.test(s)
}
合法uri
export function validateURL (textval) {
const urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
return urlregex.test(textval)
}
小写字母
export function validateLowerCase (str) {
const reg = /^[a-z]+$/
return reg.test(str)
}
大写字母
export function validateUpperCase (str) {
const reg = /^[A-Z]+$/
return reg.test(str)
}
大小写字母
export function validatAlphabets (str) {
const reg = /^[A-Za-z]+$/
return reg.test(str)
}
验证pad还是pc
export const vaildatePc = function () {
const userAgentInfo = navigator.userAgent
const Agents = ['Android', 'iPhone',
'SymbianOS', 'Windows Phone',
'iPad', 'iPod'
]
let flag = true
for (var v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
flag = false
break
}
}
return flag
}
判断姓名是否正确
export function validatename (name) {
var regName = /^[\u4e00-\u9fa5]{2,4}$/
if (!regName.test(name)) return false
return true
}
匹配8-16位数字和字母密码的正则表达式
export function validatePwd (pwd) {
var regName = /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,16}$/
if (!regName.test(pwd)) return false
return true
}
密码匹配(至少数字、字母、特殊符号两组组合)
export function validatePwd (pwd) {
var regName = /(^(?![A-Z]+$)(?![a-z]+$)(?!\d+$)(?![\W_]+$)\S+$)/
if (!regName.test(pwd)) return false
return true
}
密码匹配(密码由8位数字、大小写字母和特殊符号组成!)
export function validatePwd (pwd) {
var regName = /(^(?=.*[a-zA-Z])(?=.*\d)(?=.*[~!@#$%^&*()_+`\-={}:";'<>?,./]).{8,}$)/
if (!regName.test(pwd)) return false
return true
}
判断是否为整数
export function validatenum (num, type) {
let regName = /[^\d.]/g
if (type == 1) {
if (!regName.test(num)) return false
} else if (type == 2) {
regName = /[^\d]/g
if (!regName.test(num)) return false
}
return true
}
判断是否为小数
export function validatenumord (num, type) {
let regName = /[^\d.]/g
if (type == 1) {
if (!regName.test(num)) return false
} else if (type == 2) {
regName = /[^\d.]/g
if (!regName.test(num)) return false
}
return true
}
判断是否为空
export function validatenull (val) {
if (typeof val === 'boolean') {
return false
}
if (typeof val === 'number') {
return false
}
if (val instanceof Array) {
if (val.length == 0) return true
} else if (val instanceof Object) {
if (JSON.stringify(val) === '{}') return true
} else {
if (val == 'null' || val == null || val == 'undefined' || val == undefined || val == '') return true
return false
}
return false
}
判断身份证号码
export function cardid (code) {
let list = []
let result = true
let msg = ''
var city = {
11: '北京',
12: '天津',
13: '河北',
14: '山西',
15: '内蒙古',
21: '辽宁',
22: '吉林',
23: '黑龙江 ',
31: '上海',
32: '江苏',
33: '浙江',
34: '安徽',
35: '福建',
36: '江西',
37: '山东',
41: '河南',
42: '湖北 ',
43: '湖南',
44: '广东',
45: '广西',
46: '海南',
50: '重庆',
51: '四川',
52: '贵州',
53: '云南',
54: '西藏 ',
61: '陕西',
62: '甘肃',
63: '青海',
64: '宁夏',
65: '新疆',
71: '台湾',
81: '香港',
82: '澳门',
91: '国外 '
}
if (!validatenull(code)) {
if (code.length == 18) {
if (!code || !/(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(code)) {
msg = '证件号码格式错误'
} else if (!city[code.substr(0, 2)]) {
msg = '地址编码错误'
} else {
// 18位身份证需要验证最后一位校验位
code = code.split('')
// ∑(ai×Wi)(mod 11)
// 加权因子
var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
// 校验位
var parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2, 'x']
var sum = 0
var ai = 0
var wi = 0
for (var i = 0; i < 17; i++) {
ai = code[i]
wi = factor[i]
sum += ai * wi
}
if (parity[sum % 11] != code[17]) {
msg = '证件号码校验位错误'
} else {
result = false
}
}
} else {
msg = '证件号码长度不为18位'
}
} else {
msg = '证件号码不能为空'
}
list.push(result)
list.push(msg)
return list
}
作者: monkeysoft
转发链接:https://mp.weixin.qq.com/s/u1Ml5mKlj8Cobj6JLU0OBQ
- 上一篇:日志最佳实践 实践日志总结报告
- 下一篇:API参数如何验证?别纠结,拿去用就是
相关推荐
- 有些人能留在你的心里,但不能留在你生活里。
-
有时候,你必须要明白,有些人能留在你的心里,但不能留在你生活里。Sometimes,youhavetorealize,Somepeoplecanstayinyourheart,...
- Python学不会来打我(34)python函数爬取百度图片_附源码
-
随着人工智能和大数据的发展,图像数据的获取变得越来越重要。作为Python初学者,掌握如何从网页中抓取图片并保存到本地是一项非常实用的技能。本文将手把手教你使用Python函数编写一个简单的百度图片...
- 软网推荐:图像变变变 一“软”见分晓
-
当我们仅需要改变一些图片的分辨率、裁减尺寸、添加水印、标注文本、更改图片颜色,或将一种图片转换为另一种格式时,总比较讨厌使用一些大型的图像处理软件,尤其是当尚未安装此类软件时,更是如此。实际上,只需一...
- 首款WP8.1图片搜索应用,搜照片得资料
-
首款WP8.1图片搜索应用,搜照片得资料出处:IT之家原创(天际)2014-11-1114:32:15评论WP之家报道,《反向图片搜索》(ReverseImageSearch)是Window...
- 盗墓笔记电视剧精美海报 盗墓笔记电视剧全集高清种子下载
-
出身“老九门”世家的吴邪,因身为考古学家的父母在某次保护国家文物行动时被国外盗墓团伙杀害,吴家为保护吴邪安全将他送去德国读书,因而吴邪对“考古”事业有着与生俱来的兴趣。在一次护宝过程中他偶然获得一张...
- 微软调整Win11 24H2装机策略:6月起36款预装应用改为完整版
-
IT之家7月16日消息,微软公司今天(7月16日)发布公告,表示自今年6月更新开始,已默认更新Windows1124H2和WindowsServer2025系统中预装...
- 谷歌手把手教你成为谣言终结者 | 域外
-
刺猬公社出品,必属原创,严禁转载。合作事宜,请联系微信号:yunlugongby贾宸琰编译、整理11月23日,由谷歌新闻实验室(GoogleNewsLab)联合Bellingcat、DigD...
- NAS 部署网盘资源搜索神器:全网资源一键搜,免费看剧听歌超爽!
-
还在为找不到想看的电影、电视剧、音乐而烦恼?还在各个网盘之间来回切换,浪费大量时间?今天就教你如何在NAS上部署aipan-netdisk-search,一款强大的网盘资源搜索神器,让你全网资源...
- 使用 Docker Compose 简化 INFINI Console 与 Easysearch 环境搭建
-
前言回顾在上一篇文章《搭建持久化的INFINIConsole与Easysearch容器环境》中,我们详细介绍了如何使用基础的dockerrun命令,手动启动和配置INFINICon...
- 为庆祝杜特尔特到访,这个国家宣布全国放假?
-
(观察者网讯)近日,一篇流传甚广的脸书推文称,为庆祝杜特尔特去年访问印度,印度宣布全国放假,并举办了街头集会以示欢迎。菲媒对此做出澄清,这则消息其实是“假新闻”。据《菲律宾世界日报》2日报道,该贴子...
- 一课译词:毛骨悚然(毛骨悚然的意思是?)
-
PhotobyMoosePhotosfromPexels“毛骨悚然”,汉语成语,意思是毛发竖起,脊梁骨发冷;形容恐惧惊骇的样子(withone'shairstandingonend...
- Bing Overtakes Google in China's PC Search Market, Fueled by AI and Microsoft Ecosystem
-
ScreenshotofBingChinahomepageTMTPOST--Inastunningturnintheglobalsearchenginerace,Mic...
- 找图不求人!6个以图搜图的识图网站推荐
-
【本文由小黑盒作者@crystalz于03月08日发布,转载请标明出处!】前言以图搜图,专业说法叫“反向图片搜索引擎”,是专门用来搜索相似图片、原始图片或图片来源的方法。常用来寻找现有图片的原始发布出...
- 浏览器功能和“油管”有什么关联?为什么要下载
-
现在有没有一款插件可以实现全部的功能,同时占用又小呢,主题主要是网站的一个外观,而且插件则主要是实现wordpress网站的一些功能,它不仅仅可以定制网站的外观,还可以实现很多插件的功能,搭载chro...
- 一周热门
- 最近发表
- 标签列表
-
- mybatiscollection (79)
- mqtt服务器 (88)
- keyerror (78)
- c#map (65)
- xftp6 (83)
- bt搜索 (75)
- c#var (76)
- xcode-select (66)
- mysql授权 (74)
- 下载测试 (70)
- linuxlink (65)
- pythonwget (67)
- androidinclude (65)
- libcrypto.so (74)
- linux安装minio (74)
- ubuntuunzip (67)
- vscode使用技巧 (83)
- secure-file-priv (67)
- vue阻止冒泡 (67)
- jquery跨域 (68)
- php写入文件 (73)
- kafkatools (66)
- mysql导出数据库 (66)
- jquery鼠标移入移出 (71)
- 取小数点后两位的函数 (73)