js工具函数大全
标签搜索

js工具函数大全

指针原来是套娃的
2024-10-09 / 0 评论 / 8 阅读 / 正在检测是否收录...

效验相关


/**
 * 手机号码
 * @param val 当前值字符串
 * @returns 返回 true: 手机号码正确
 */
export function verifyPhone(val) {
  // false: 手机号码不正确
  // if (
  //   !/^((12[0-9])|(13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(16([0-3]|[5-9]))|(17([0-3]|[5-9]))|(18[0,5-9]))\d{8}$/.test(
  //     val
  //   )
  // ) {
  if (!/^1[3-9]\d{9}$/.test(val)) {
    return false
  } else {
    return true
  }
}

/**
 * 国内电话号码
 * @param val 当前值字符串
 * @returns 返回 true: 国内电话号码正确
 */
export function verifyTelPhone(val) {
  // false: 国内电话号码不正确
  if (!/\d{3}-\d{8}|\d{4}-\d{7}/.test(val)) return false
  // true: 国内电话号码正确
  else return true
}

/**
 * 密码 (以字母开头,长度在6~16之间,只能包含字母、数字和下划线)
 * @param val 当前值字符串
 * @returns 返回 true: 密码正确
 */
export function verifyPassword(val) {
  // false: 密码不正确
  if (!/^[a-zA-Z]\w{5,15}$/.test(val)) return false
  // true: 密码正确
  else return true
}

/**
 * 强密码 (字母+数字+特殊字符,长度在6-16之间)
 * @param val 当前值字符串
 * @returns 返回 true: 强密码正确
 */
export function verifyPasswordPowerful(val) {
  // false: 强密码不正确
  if (
    !/^(?![a-zA-z]+$)(?!\d+$)(?![!@#$%^&\.*]+$)(?![a-zA-z\d]+$)(?![a-zA-z!@#$%^&\.*]+$)(?![\d!@#$%^&\.*]+$)[a-zA-Z\d!@#$%^&\.*]{6,16}$/.test(
      val
    )
  ) {
    return false
  } else {
    return true
  }
}

/**
 * 密码强度
 * @param val 当前值字符串
 * @description 弱:纯数字,纯字母,纯特殊字符
 * @description 中:字母+数字,字母+特殊字符,数字+特殊字符
 * @description 强:字母+数字+特殊字符
 * @returns 返回处理后的字符串:弱、中、强
 */
export function verifyPasswordStrength(val) {
  let v = ''
  // 弱:纯数字,纯字母,纯特殊字符
  if (/^(?:\d+|[a-zA-Z]+|[!@#$%^&\.*]+){6,16}$/.test(val)) v = '弱'
  // 中:字母+数字,字母+特殊字符,数字+特殊字符
  if (/^(?![a-zA-z]+$)(?!\d+$)(?![!@#$%^&\.*]+$)[a-zA-Z\d!@#$%^&\.*]{6,16}$/.test(val)) v = '中'
  // 强:字母+数字+特殊字符
  if (
    /^(?![a-zA-z]+$)(?!\d+$)(?![!@#$%^&\.*]+$)(?![a-zA-z\d]+$)(?![a-zA-z!@#$%^&\.*]+$)(?![\d!@#$%^&\.*]+$)[a-zA-Z\d!@#$%^&\.*]{6,16}$/.test(
      val
    )
  ) {
    v = '强'
  }
  // 返回结果
  return v
}

/**
 * IP地址
 * @param val 当前值字符串
 * @returns 返回 true: IP地址正确
 */
export function verifyIPAddress(val) {
  // false: IP地址不正确
  if (
    !/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/.test(
      val
    )
  ) {
    return false
  } else {
    return true
  }
}

/**
 * 邮箱
 * @param val 当前值字符串
 * @returns 返回 true: 邮箱正确
 */
export function verifyEmail(val) {
  // false: 邮箱不正确
  if (
    !/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
      val
    )
  ) {
    return false
  } else {
    return true
  }
}

/**
 * 身份证
 * @param val 当前值字符串
 * @returns 返回 true: 身份证正确
 */
export function verifyIdCard(val) {
  // false: 身份证不正确
  /**
   * 表达式解释
   * ^[1-9]\d{5}:身份证号码的前6位是行政区划代码,以1-9的数字开头,后面跟着5个数字。
   * (18|19|20)\d{2}:接下来的4位是年份,可以是18、19或20开头的年份。
   * (0[1-9]|1[0-2]):接下来的2位是月份,01到12之间的数字。
   * (0[1-9]|[12]\d|3[01]):接下来的2位是日期,可以是01到31之间的数字。
   * \d{3}:接下来的3位是顺序码,通常是随机生成的数字。
   * [\dxX]$:最后一位是校验位,可以是数字、小写字母x或大写字母X,用于校验身份证号码的合法性。
   */
  if (!/^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dxX]$/.test(val)) {
    return false
  } else {
    return true
  }
}
/**
 * 姓名
 * @param val 当前值字符串
 * @returns 返回 true: 姓名正确
 */
export function verifyFullName(val) {
  // false: 姓名不正确
  if (!/^[\u4e00-\u9fa5]{1,6}(·[\u4e00-\u9fa5]{1,6}){0,2}$/.test(val)) return false
  // true: 姓名正确
  else return true
}

/**
 * 邮政编码
 * @param val 当前值字符串
 * @returns 返回 true: 邮政编码正确
 */
export function verifyPostalCode(val) {
  // false: 邮政编码不正确
  if (!/^[1-9][0-9]{5}$/.test(val)) return false
  // true: 邮政编码正确
  else return true
}

/**
 * url 处理
 * @param val 当前值字符串
 * @returns 返回 true: url 正确
 */
export function verifyUrl(val) {
  // false: url不正确
  if (
    !/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(
      val
    )
  ) {
    return false
  } else {
    return true
  }
}
/**
 * 验证码位数校验
 * @param {*} val 验证码
 * @param {*} num 验证码位数
 */
export function verifyCode(val) {
  const reg = new RegExp(/^[0-9]\d{5}$/)
  if (!reg.test(val)) return false
  else return true
}

/**
 * 验证百分比(不可以小数)
 * @param val 当前值字符串
 * @returns 返回处理后的字符串
 */
export function verifyNumberPercentage(val) {
  // 匹配空格
  let v = val.replace(/(^\s*)|(\s*$)/g, '')
  // 只能是数字和小数点,不能是其他输入
  v = v.replace(/[^\d]/g, '')
  // 不能以0开始
  v = v.replace(/^0/g, '')
  // 数字超过100,赋值成最大值100
  v = v.replace(/^[1-9]\d\d{1,3}$/, '100')
  // 返回结果
  return v
}

/**
 * 验证百分比(可以小数)
 * @param val 当前值字符串
 * @returns 返回处理后的字符串
 */
export function verifyNumberPercentageFloat(val) {
  let v = verifyNumberIntegerAndFloat(val)
  // 数字超过100,赋值成最大值100
  v = v.replace(/^[1-9]\d\d{1,3}$/, '100')
  // 超过100之后不给再输入值
  v = v.replace(/^100\.$/, '100')
  // 返回结果
  return v
}

/**
 * 小数或整数(不可以负数)
 * @param val 当前值字符串
 * @returns 返回处理后的字符串
 */
export function verifyNumberIntegerAndFloat(val) {
  // 匹配空格
  let v = val.replace(/(^\s*)|(\s*$)/g, '')
  // 只能是数字和小数点,不能是其他输入
  v = v.replace(/[^\d.]/g, '')
  // 以0开始只能输入一个
  v = v.replace(/^0{2}$/g, '0')
  // 保证第一位只能是数字,不能是点
  v = v.replace(/^\./g, '')
  // 小数只能出现1位
  v = v.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.')
  // 小数点后面保留2位
  v = v.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3')
  // 返回结果
  return v
}

/**
 * 检测是否是Number类型,排除NaN
 */
export function isNumber(number) {
  return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(number)
}

/**
 * 正整数验证
 * @param val 当前值字符串
 * @returns 返回处理后的字符串
 */
export function verifiyNumberInteger(val) {
  // 匹配空格
  let v = val.replace(/(^\s*)|(\s*$)/g, '')
  // 去掉 '.' , 防止贴贴的时候出现问题 如 0.1.12.12
  v = v.replace(/[\.]*/g, '')
  // 去掉以 0 开始后面的数, 防止贴贴的时候出现问题 如 00121323
  v = v.replace(/(^0[\d]*)$/g, '0')
  // 首位是0,只能出现一次
  v = v.replace(/^0\d$/g, '0')
  // 只匹配数字
  v = v.replace(/[^\d]/g, '')
  // 返回结果
  return v
}


/**
 * 去掉中文及空格
 * @param val 当前值字符串
 * @returns 返回处理后的字符串
 */
export function verifyCnAndSpace(val) {
  // 匹配中文与空格
  let v = val.replace(/[\u4e00-\u9fa5\s]+/g, '')
  // 匹配空格
  v = v.replace(/(^\s*)|(\s*$)/g, '')
  // 返回结果
  return v
}

/**
 * 去掉英文及空格
 * @param val 当前值字符串
 * @returns 返回处理后的字符串
 */
export function verifyEnAndSpace(val) {
  // 匹配英文与空格
  let v = val.replace(/[a-zA-Z]+/g, '')
  // 匹配空格
  v = v.replace(/(^\s*)|(\s*$)/g, '')
  // 返回结果
  return v
}

/**
 * 禁止输入空格
 * @param val 当前值字符串
 * @returns 返回处理后的字符串
 */
export function verifyAndSpace(val) {
  // 匹配空格
  const v = val.replace(/(^\s*)|(\s*$)/g, '')
  // 返回结果
  return v
}

文件相关

export const downloadFile = (url = '', fileName = '未知文件', cb) => {
  const a = document.createElement('a')
  a.style.display = 'none'
  a.setAttribute('target', '_blank')
  /*
   * download的属性是HTML5新增的属性
   * href属性的地址必须是非跨域的地址,如果引用的是第三方的网站或者说是前后端分离的项目(调用后台的接口),这时download就会不起作用。
   * 此时,如果是下载浏览器无法解析的文件,例如.exe,.xlsx..那么浏览器会自动下载,但是如果使用浏览器可以解析的文件,比如.txt,.png,.pdf....浏览器就会采取预览模式
   * 所以,对于.txt,.png,.pdf等的预览功能我们就可以直接不设置download属性(前提是后端响应头的Content-Type: application/octet-stream,如果为application/pdf浏览器则会判断文件为 pdf ,自动执行预览的策略)
   */
  fileName && a.setAttribute('download', fileName)
  a.href = url
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  cb && cb()
}

export const downloadBlob = (data, fileName = '未知文件.xlsx', type) => {
  const blob = new Blob([data], { type }) // 处理文档流
  const a = document.createElement('a') // 创建a标签
  a.download = fileName.replace(new RegExp('"', 'g'), '')
  a.style.display = 'none'
  a.href = URL.createObjectURL(blob) // 创建blob地址
  document.body.appendChild(a) // 将a标签添加到body中
  a.click()
  URL.revokeObjectURL(a.href) // 释放URL对象
  document.body.removeChild(a) // 从body中移除a标签
}

/**
 * 文件大小转换对应单位大小
 * @param size 文件大小,字节(B)单位
 * @returns 返回 string
 */
export function transformFileSizeUnit(size) {
  if (!size) return ''
  let sizestr = ''
  if (size < 0.1 * 1024) {
    // 如果小于0.1KB转化成B
    sizestr = size.toFixed(2) + 'B'
  } else if (size < 1 * 1024 * 1024) {
    // 如果小于1MB转化成KB
    sizestr = (size / 1024).toFixed(2) + 'KB'
  } else if (size < 1 * 1024 * 1024 * 1024) {
    // 如果小于1GB转化成MB
    sizestr = (size / (1024 * 1024)).toFixed(2) + 'MB'
  } else {
    // 其他转化成GB
    sizestr = (size / (1024 * 1024 * 1024)).toFixed(2) + 'GB'
  }

  return sizestr.replace('.00', '')
}

/**
 * @description: 将 BASE64 转换文件
 * @param {*}
 * @return {*}
 */
export const dataURLtoFile = (dataurl, filename) => {
  const arr = dataurl.split(',');
  const mime = arr[0].match(/:(.*?);/)[1];
  if (!filename) filename = `${Date.parse(new Date())}.jpg`;
  const bstr = window.atob(arr[1]);
  let n = bstr.length;
  const u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new File([u8arr], filename, { type: mime });
}

工具函数


/**
 * 金额用 `,` 区分开
 * @param val 当前值字符串
 * @returns 返回处理后的字符串
 */
export function verifyNumberComma(val) {
  // 调用小数或整数(不可以负数)方法
  let v = verifyNumberIntegerAndFloat(val)
  // 字符串转成数组
  v = v.toString().split('.')
  // \B 匹配非单词边界,两边都是单词字符或者两边都是非单词字符
  v[0] = v[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',')
  // 数组转字符串
  v = v.join('.')
  // 返回结果
  return v
}

/**
 * 匹配文字变色(搜索时)
 * @param val 当前值字符串
 * @param text 要处理的字符串值
 * @param color 搜索到时字体高亮颜色
 * @returns 返回处理后的字符串
 */
export function verifyTextColor(val, text = '', color = 'red') {
  // 返回内容,添加颜色
  const v = text.replace(new RegExp(val, 'gi'), `<span style='color: ${color}'>${val}</span>`)
  // 返回结果
  return v
}

/**
 * 数字转中文大写
 * @param val 当前值字符串
 * @param unit 默认:仟佰拾亿仟佰拾万仟佰拾元角分
 * @returns 返回处理后的字符串
 */
export function verifyNumberCnUppercase(val, unit = '仟佰拾亿仟佰拾万仟佰拾元角分', v = '') {
  // 当前内容字符串添加 2个0,为什么??
  val += '00'
  // 返回某个指定的字符串值在字符串中首次出现的位置,没有出现,则该方法返回 -1
  const lookup = val.indexOf('.')
  // substring:不包含结束下标内容,substr:包含结束下标内容
  if (lookup >= 0) val = val.substring(0, lookup) + val.substr(lookup + 1, 2)
  // 根据内容 val 的长度,截取返回对应大写
  unit = unit.substr(unit.length - val.length)
  // 循环截取拼接大写
  for (let i = 0; i < val.length; i++) {
    v += '零壹贰叁肆伍陆柒捌玖'.substr(val.substr(i, 1), 1) + unit.substr(i, 1)
  }
  // 正则处理
  v = v
    .replace(/零角零分$/, '整')
    .replace(/零[仟佰拾]/g, '零')
    .replace(/零{2,}/g, '零')
    .replace(/零([亿|万])/g, '$1')
    .replace(/零+元/, '元')
    .replace(/亿零{0,3}万/, '亿')
    .replace(/^元/, '零元')
  // 返回结果
  return v
}
/**
 * 多维数组去重(包含对象)
 * @param {Array} arrayData // 需要去重的数组
 * @param {String} key // 根据属性进行去重
 */
export const multiArrayDedup = (arrayData = [], key = '') => {
  const hashKey = {}
  const result = [
    ...new Set(
      arrayData.reduce((item, next) => {
        return item.concat(next)
      }, [])
    )
  ].reduce((item, next) => {
    if (next[key]) {
      // eslint-disable-next-line no-unused-expressions
      hashKey[next[key]] ? '' : (hashKey[next[key]] = true && item.push(next))
    } else {
      item.push(next)
    }
    return item
  }, [])
  return result
}

/**
 * 对象数组去重
 * @param {Array} arrayData // 需要去重的数组
 * @param {String} key // 根据属性进行去重
 */
export const objectArrayDedup = (arrayData = [], key = '') => {
  const hash = {} // 缓存对象数组里的某一个属性
  const result = arrayData.reduce((item, next, index, data) => {
    // eslint-disable-next-line no-unused-expressions
    hash[next[key]] ? '' : (hash[next[key]] = true && item.push(next))
    return item
  }, [])
  return result
}

/**
 * 普通数组去重
 * @param {Array} arrayData // 需要去重的数组
 */
export const normalArrayDedup = (arrayData = []) => {
  const result = arrayData.reduce((item, next) => {
    item.indexOf(next) === -1 && item.push(next)
    return item
  }, [])
  return result
}

/**
 * 判断是否文本溢出
 * @param e 事件对象
 * @returns  返回true为未溢出  false溢出
 */
export const isBeyond = e => {
  const ev = window.event || e
  const textRange = el => {
    const textContent = el
    const targetW = textContent.getBoundingClientRect().width
    const range = document.createRange()
    range.setStart(textContent, 0)
    range.setEnd(textContent, textContent.childNodes.length)
    const rangeWidth = range.getBoundingClientRect().width
    return rangeWidth > targetW
  }
  return !textRange(ev.target)
}

// 获取字数 中文单字算一个字数 英文按空格算一个字数
// 例如:a app 两个字数
// a app 很好 四个字数
export const tokenizeLens = text => {
  // 英文分词:按空格分词
  const englishTokens = text.split(' ')

  // 中文分词:按单个字符分词
  const chineseTokens = text.split('').filter(char => /[\u4e00-\u9fff]/.test(char))

  // 合并英文字符和中文单字
  const tokens = englishTokens.concat(chineseTokens)

  // 返回词汇总数
  return tokens.length
}
1

评论

博主关闭了所有页面的评论