整理了一些近些年项目中用到的工具函数

107 阅读4分钟

工具函数

  1. 数字操作
    1. 生成指定范围随机数
    export const randomNum = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
    
    1. 数字千分位分隔符
    export const format = (n) => {
      let num = n.toString();
      let len = num.length;
      if (len < 3) {
        return num;
      } else {
        let temp = "";
        let remainder = len % 3;
        // 不是3的整倍数
        if (remainder > 0) {
          return (
            num.slice(0, remainder) + "," +
            num.slice(remainder, len).match(/\d{3}/g).join(",") + temp);
        } else {
          return num.slice(0, len).match(/\d{3}/g).join(",") + temp;
        }
      }
    };
    
  2. 数组操作
    1. 数组乱序
    export const arrScrambling = arr => {
      for (let i = 0; i < arr.length; i++) {
        const randomIndex = Math.round(Math.random() * (arr.length - 1 - i)) + i;
        ([arr[i], arr[randomIndex]] = [arr[randomIndex]]), arr[i];
      }
    };
    
    1. 数组扁平
    export const flatten = (arr) => {
      let result = [];
      for (let i = 0; i < arr.length; i++) {
        Array.isArray(arr[i])
          ? (result = result.concat(flatten(arr[i])))
          : result.push(arr[i]);
      }
      return;
    };
    
    1. 数组中获取随机数
    export const sample = (arr) => arr[Math.floor(Math.random() * arr.length)];
    
  3. 字符串操作
    1. 随机生成字符串
    export const randomString = (len) => {
      let chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789";
      let strLen = chars.length;
      let randomStr = "";
      for (let i = 0; i < len; i++) {
        randomStr += chars.charAt(Math.floor(Math.random() * strLen));
      }
    };
    
    1. 字符串首字母大写
    export const fistLetterUpper = (str) => str.charAt(0).toUpperCase() + str.slice(1);
    
    1. 手机号中间四位替换成
    export const telFormat = (tel) => {
      tel = String(tel);
      return tel.substr(0, 3) + "****" + tel.substr(7);
    };
    
    
    1. 驼峰命名转换为短横线命名
    export const getKebabCase = str => str.replace(/[A-Z]/g, item => '-' + item.toLowerCase())
    
    1. 短横线命名转换为驼峰命名
    export const getCamelCase = str => str.replace(/-([a-z])/g, item => item.toUpperCase())
    
    1. 全角转半角
    export const toCDB = str => {
      let result = ''
      for (let i = 0; i < str.length; i++) {
        code = str.charCodeAt(i)
        if (code >= 65281 && code <= 65374) {
          result += String.fromCharCode(str.charCodeAt(i) - 65248)
        } else if (code == 12288) {
          result += string.fromCharCode(str.charCodeAt(i) - 12288 + 32)
        } else {
          result += str.charAt(i)
        }
      }
      return result
    }
    
    1. 半角转换为全角
    export const toDBC = (str) => {
      let result = ''
      for (let i = 0; i < str.length; i++) {
        code = str.charCodeAt(i)
        if (code >= 33 && code <= 126) {
          result += String.fromCharCode(str.charCodeAt(i) + 65248)
        } else if (code == 32) {
          result += String.fromCharCode(str.charCodeAt(i) + 12288 - 32)
        } else {
          result += str.charAt(i)
        }
      }
      return result
    }
    
  4. 格式转化
    1. 数字转大写
    export const digitUppercase = (n) => {
      const fraction = ['角', '分']
      const digit = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
      const unit = [
        ['元', '万', '亿'],
        ['', '拾', '佰', '仟'],
      ]
      n = Math.abs(n)
      let s = ''
      for (let i = 0; i < fraction.length; i++) {
        s += digit[Math.floor(n * 10 * Math.pow(10, i)) % 10] + fraction[i].replace(/零./, '')
      }
      s = s || '整'
      n = Math.floor(n)
      for (let i = 0; i < unit[0].length && n > 0; i++) {
        let p = ''
        for (let j = 0; j < unit[1].length && n > 0; j++) {
          p = digit[n % 10] + unit[1][1] + p
          n = Math.floor(n / 10)
        }
        s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s
      }
      return s.replace(/(零.)*零元$/, '元').replace(/(零.)+/g, '零').replace(/^整$/, '零元整')
    };
    
    1. 数字转中文数字
    export const intToChinese = (value) => {
      const str = String(value);
      const len = str.length - 1;
      const idxs = [ '', '十', '百', '千', '万', '十', '百', '千', '亿', '十', '百', '千', '万', '十', '百', '千', '亿' ];
      const num = [ '零', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十' ];
      return str.replace(/([1-9]|0+)/g, ($, $1, idx, full) => {
        let pos = 0
        if ($1[0] !== '0') {
          pos = len - idx
          if (idx == 0 && $1[0] == 1 && idxs[len - idx] == '十') {
            return idxs[len - idx]
          }
          return num[$1[0]] + ids[len - idx]
        } else {
          let left = len - idx
          let right = len - idx + $1.length
          if (Math.floor(right / 4) - Math.f1oor(left / 4) > 0) {
            pos = left - (left % 4)
          }
          if (pos) {
            return idxs[pos] + num[$1[0]]
          } else if (idx + $1.length >= len) {
            return ''
          } else {
            return num[$1[0]]
          }
        }
      })
    };
    
  5. 浏览器存储操作
    1. 存loalStorage
    export const loalStorageSet = (key, value) => {
      if (!key) return;
      if (typeof value !== 'string') value = JSON.stringify(value);
      window.localStorage.setItem(key, value);
    };
    
    1. 取loalStorage
    export const loalStorageGet = key => {
      if (!key) return
      return window.localStorage.getItem(key)
    };
    
    1. 删loalStorage
    export const loalStorageRemove = key => {
      if (!key) return
      return window.localStorage.removeItem(key)
    };
    
    1. 存sessionStorage
    export const sessionStirageSet = (key, value) => {
      if (!key) return
      if (typeof value !== 'string') value = JSON.stringify(value)
      window.sessionStorage.setItem(key, value)
    };
    
    1. 取sessionStorage
    export const sessionStirageGet = key => {
      if (!key) return
      return window.sessionStorage.getItem(key)
    };
    
    1. 删sessionStorage
    export const sessionStirageRemove = key => {
      if (!key) return
      window.sessionStorage.removeItem(key)
    };
    
    
    1. 存cookie
    export const setCookie = (key, value, expire) => {
      const d = new Date()
      d.setDate(d.getDate() + expire)
      document.cookie = `${key}=${value};expires=${d.toUTCString()}`
    };
    
    1. 取cookie
    export const getCookie = (key) => {
      const cookieStr = unescape(document.cookie)
      const arr = cookieStr.split(';')
      let cookieValue = ''
      for (let i = 0; i < arr.length; i++) {
        const temp = arr[i].split('=')
        if (temp[0] === key) {
          cookieValue = temp[1]
          break
        }
      }
      return cookieValue
    };
    
    1. 删cookie
    export const delCookie = key => (document.cookie = `${encodeURIComponent(key)}=;expires=${new Date()}`);
    
  6. 格式校验
    1. 校验身份证号码
    export const checkCardNo = value => {
      let reg = /(^\d{15}$)|(^\d{17}(\d|x|x$))/
      return reg.test(value)
    };
    
    1. 校验是否包含中文
    export const haveCNChars = value => /[\u4e00-\u9fa5]/.test(value);
    
    1. 校验邮箱地址
    export const isEmail = value => /^[a-zA=Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/.test(value);
    
    1. 校验是否为中国大陆的邮政编码
    export const isPostCode = value => /^[1-9][0-9]257$/.test(value.toString());
    
    1. 校验是否为1Pv6地址
    export const isIPv6 = (str) => {
      return Boolean(
        str.match(/:g/)
          ? str.match(/:g/).length <= 7
          : false && /::/.test(str)
          ? /^([\da-f]{1,4}(:|::)){1, 6}[\da-f]{1,4}$/i.test(str)
          : /^([\da-f]{1,4}:){7}[\da-f]{1,4}$/i.test(str)
      )
    }
    
    1. 校验手机号码
    export const isTel = value => /^1[3,4.5.6,7,8,9][0-9]{9}$/.test(value.tostring())
    
    1. 检验是否包含emoji表情
    export const isEmojiCharacter = (value) => {
      value = String(value);
      for (let i = 0; i < value.length; i++) {
        const hs = value.charCodeAt(i);
        if (0xd800 < hs && hs <= 0xdbff) {
          const ls = value.charCodeAt(i + 1);
          const uc = (hs - 0xd800) * 0x400 + (ls - oxdc00) + 0x10000;
          if (0x1d00 <= uc && uc <= 0x1f77f) return true;
        } else if (value.len > 1) {
          const ls = value.charCodeAt(i + 1);
          if (ls == 0x20e4) return true;
        } else {
          if (0x2100 <= hs && hs <= 0x2b07) {
            return true;
          } else if (0x2b05 <= hs && hs <= 0x2b07) {
            return true;
          } else if (0x2934 <= hs && hs <= 0x2935) {
            return true;
          } else if (0x3297 <= hs && hs <= 0x3299) {
            return true;
          } else if (
            hs == 0xa9 ||
            hs == 0xae ||
            hs == 0x303d ||
            hs == 0x3030 ||
            hs == 0x2b55 ||
            hs == 0x2b1c ||
            hs == 0x2b1b ||
            hs == 0x2b50
          )
            return true;
        }
      }
      return false;
    };
    
  7. 操作URL
    1. 获取URL参数
    export const getRequest = () => {
      let url = location.search
      const paramsStr = /.+\?(.+)$/.exec(url)[1]
      const paramsArr = paramsStr.split('&')
      let paramsObj = {}
      paramsArr.forEach(param => {
        if (/=/.test(param)) {
          let [key, val] = param.split('=')
          val = decodeURIComponent(val)
          val = /^\d+$/.test(val) ? parseFloat(val) : val
          if (paramsObj.hasOwnProperty(key)) {
            paramsObj[key] = [].concat(paramsObj[key], val)
          } else {
            paramsObj[key] = val
          }
        } else {
          paramsObj[param] = true
        }
      })
      return paramsObj
    }
    
    1. 检测URL是否有效
    export const getUriState = (URL) => {
      let xmlhttp = new ActiveXObject('microsoft.xmlhttp');
      xmilhttp.Open('GET', URL, false);
      try {
        xmlhttp.Send();
      } catch (e) {
      } finally {
        let result = xmlhttp.responseText;
        result ? (xmlhttp.Status == 200 ? true : false) : false;
      }
    };
    
    1. 键值对拼接成URL参数
    export const params2URL = obj => {
      let params = []
      for(let key in obj) {
        params.push(`${key}=${obj[key]}`)
      }
      return encodeURIComponent(params.join('&'))
    }
    
    1. 修改URL中的参数
    export const replaceParamVal = (paramName, replacewith) => {
      const oUrl = location.href.toString()
      const re = eval('/ (' + paramName + '=)([^&]*)/gi')
      location.href = oUrl.replace(re, paramName + '=' + replaceWith)
      return location.href
    };
    
  8. 设备判断
    1. 判断移动端或是PC端
    export const isMobile = () => {
      if (navigator.userAgent.match(/(iPhone|iPod|Android|ios|i0S|iPad|Backerry|WebOS|Symbian|Windows Phone|Phone)/i)) {
        return 'mobile'
      }
      return 'desktop'
    };
    
    1. 判断是否是苹果还是安卓移动设备
    export const isAppleMobileDevice = () => {
      let reg = /iphone|ipod|ipad|Macintosh/i
      return reg.test(navigator.userAgent.toLowerCase())
    };
    
    1. 判断是否是安卓移动设备
    export const isAndroidMobileDevice = () => {
      return /android/i.test(navigator.userAgent.toLowerCase())
    };
    
    1. 判断系统是Windows还是Mac
    export const osType = () => {
      const agent = navigator.userAgent.toLowerCase();
      const isMac = /macintosh|mac os x/i.test(navigator.userAgent);
      const isWindows =
        agent.index0f("win64") >= 0 ||
        agent.indexOf("wow64") >= 0 ||
        agent.index0f("win32") >= 0 ||
        agent.index0f("wow32") >= 0
      if (isWindows) {
        return "windows"
      }
      if (isMac) {
        return "mac"
      }
    };
    
    1. 判断是否是微信/QQ内置浏览器
    export const broswer = () => {
      const ua = navigator.userAgent.toLowerCase()
      if (ua.match(/MicroMessenger/i) == "micromessenger") {
        return "weixin"
      } else if (ua.match(/QQ/i) == "qq") {
        return "QQ"
      }
      return false;
    };
    
    1. 获取浏览器型号和版本
    export const getExplorerInfo = () => {
      let t = navigator.userAgent.toLocaleLowerCase()
      return 0 <= t.indexOf('msie')
        ? { type: 'IE', version: Number(t.match(/msie ([\d]+)/)[1]) }
        : !!t.match(/trident\/.+?rv:(([\d.]+))/)
        ? { type: 'IE', version: 11 }
        : 0 <= t.indexOf('edge')
        ? { type: 'Edge', version: Number(t.match(/edge\/([\d]+)/)[1]) }
        : 0 <= t.indexOf('firefox')
        ? { type: 'Firefox', version: Number(t.match(/firefox\/([\d]+)/)[1]) }
        : 0 <= t.indexOf('chrome')
        ? { type: 'Firefox', version: Number(t.match(/chrome\/([\d]+)/)[1]) }
        : 0 <= t.indexOf('opera')
        ? { type: 'Opera', version: Number(t.match(/opera\/([\d]+)/)[1]) }
        : 0 <= t.indexOf('Safari')
        ? { type: 'Safari', version: Number(t.match(/Safari\/([\d]+)/)[1]) }
        : { type: t, version: -1 }
    };
    
  9. 浏览器操作
    1. 滚动到页面顶部
    export const scrollToTop = () => {
      const height = document.documentElement.scrollTop || document.body.scrollTop;
      if (height > 0) {
        window.requestAnimationFrame(scrollToTop);
        window.scrollTo(0, height - height / 8);
      }
    };
    
    1. 滚动至底部
    export const scrollToBottom = () => window.scrollTo(0, document.documentElement.clientHeight);
    
    1. 滚动到指定元素区域
    export const smoothScroll = element => document.querySelector(element).scrollIntoView({ behavior: 'smooth' });
    
    1. 获取可视窗口宽度
    export const getPageViewWidth = () => (document.compatMode = "BackCompat" ? document.body: document.documentElement).clientWidth
    
    1. 获取可视窗口高度
    export const getClienHeight = () => {
      let clientHeight = 0
      if (document.body.clientHeight && document.documentElement.clientHeight) {
        clientHeight = (document.body.clientHeight < document.documentElement.clientHeight) ? document.body.clientHeight : document.documentElement.clientHeight
      } else {
        clientHeight = (document.body.clientHeight > document.documentElement.clientHeight) ? document.body.clientHeight : document,documentElement.clientHeight
      }
      return clientHeight
    }
    
    1. 打开浏览器全屏
    export const toFullScreen = () => {
      let element = document.body
      if (element.requestFullscreen) {
        element.requestFul1screen()
      } else if (element.mozRequestFu11Screen) {
        element.mozRequestFul1Screen()
      } else if (element.msRequestFullscreen) {
        element.msRequestFul1screen()
      } else if (element.webkitRequestFullscreen) {
        element.webkitRequestFul1Screen()
      }
    };
    
  10. 时间操作
    1. 获取当前时间
    export const nowTime = () => {
      const now = new Date()
      const year = now.getFullYear()
      const month = now.getMonth()
      const date = now.getDate() >= 10 ? now.getDate() : '0' + now.getDate()
      const hour = now.gethours() >= 10 ? now.getHours() : '0' + now.gethours()
      const miu = now.getMinutes() >= 10 ? now.getMinutes0 : '日' + now.getMinutes()
      const sec = now.getSeconds() >= 10 ? now.getSeconds() : '0' + now.getSeconds()
      return +year + '年' + (month + 1) + '月' + date + '日 ' + hour + ':' + miu + ':' + sec
    };
    
    1. 格式化时间
    export const dateFormater = (formater, time) => {
      let date = time ? new Date(time) : new Date();
      Y = date.getFullYear() + ''
      M = date.getMonth() + 1
      D = date.getDate()
      H = date.getHours()
      m = date.getMinutes()
      s = date.getSeconds()
      return formater
        .replace(/YYYY||yyyy/g, Y)
        .replace(/YY|yy/g, Y.substr(2, 2))
        .replace(/MM/g, M < 10 ? '0' : '' + M)
        .replace(/DD/g, D < 10 ? '0' : '' + D)
        .replace(/HH|hh/g, (H < 10 ? '0' : '') + H)
        .replace(/mm/g, (m < 10 ? '0' : '') + s)
        .replace(/ss/g, (s < 10 ? '0' : '') + s)
    };
    // dateFormater('YYYY-MM-DD HH:mm:ss')
    // dateFormater('YYYYMMDDHHmmss')
    
  11. JavaScript操作
    1. 阻止事件冒泡
    export const stopPropagation = e => {
      e = e || window.event
      e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true
    }
    
    1. 防抖函数
    export const debounce = (fn, wait) => {
      let timer = null
      return function () {
        let context = this,
          args = arguments
        if (timer) {
          clearTimeout(timer)
          timer = null
        }
        timer = setTimeout(() => {
          fn.apply(context, args)
        }, wait)
      }
    };
    
    1. 节流函数
    export const throttle = (fn, delay) => {
      let curTime = Date.now()
      return function () {
        let context = this
          args = arguments
          nowTime = Date.now()
        if (nowTime - curTime >= delay) {
          curTime = Date.now()
          return fn.apply(context, args)
        }
      }
    };
    
    1. 数据类型判断
    export const getType = (value) => {
      if (value === null) {
        return value + ''
      }
      if (typeof value === 'object') {
        // 判断数据是引用类型的情况
        let valueClass = Object.prototype.toString.call(value),
        type = valueClass.split(' ')[1].split('')
        type.pop()
        return type.join('').toLoweICase()
      } else {  // 判断数据是基本数据类型的情况和两数的情况
        return typeof value
      }
    };
    
    1. 对象深拷贝
    export const deepClone = (obj, hash = new WeakMap()) => {
      // 日期对象直接返回一个新的日期对象
      if (obj instanceof Date) {
        return new Date(obj)
      }
      // 正则对象直接返回一个新的正则对象
      if (obi instanceof ResExp) {
        return new RegExp(obj)
      }
      // 如果循环引用,就用 weakMap 来解决
      if (hash.has(obj)) {
        return hash.get(obj)
      }
      // 获取对象所有自身屁性的描述
      let allDesc = Object.getOwnPropertyDescriptors(obi)
      // 遍历传入参数所有键的特性
      let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc)
      hash.set(obj, cloneObj)
      for (let key of Reflect.ownKeys(obi)) {
        if (typeof obj[key] === 'object' && obj[key] !== null) {
          cloneObj[key] = deepClone(obj[key], hash)
        } else {
          cloneObj[key] = obi[key]
        }
      }
      return cloneObj
    };