• JS 工具函数助力高效开发 - 齐枭飞 - web前端专家


    JS 工具函数助力高效开发

    1、校验数据类型

    export const typeOf = function(obj) {
      return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase()
    }
    
    • 1
    • 2
    • 3

    示例:

    typeOf('树哥')  // string
    typeOf([])  // array
    typeOf(new Date())  // date
    typeOf(null) // null
    typeOf(true) // boolean
    typeOf(() => { }) // function
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2、防抖

    export const debounce = (() => {
      let timer = null
      return (callback, wait = 800) => {
        timer&&clearTimeout(timer)
        timer = setTimeout(callback, wait)
      }
    })()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    示例:

    如 vue 中使用
    // methods: {
    //   loadList() {
    //     debounce(() => {
    //       console.log('加载数据')
    //     }, 500)
    //   }
    // }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3、节流

    export const throttle = (() => {
      let last = 0
      return (callback, wait = 800) => {
        let now = +new Date()
        if (now - last > wait) {
          callback()
          last = now
        }
      }
    })()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4、手机号脱敏

    export const hideMobile = (mobile) => {
      return mobile.replace(/^(\d{3})\d{4}(\d{4})$/, "$1****$2")
    }
    
    • 1
    • 2
    • 3

    5、开启全屏

    export const launchFullscreen = (element) => {
      if (element.requestFullscreen) {
        element.requestFullscreen()
      } else if (element.mozRequestFullScreen) {
        element.mozRequestFullScreen()
      } else if (element.msRequestFullscreen) {
        element.msRequestFullscreen()
      } else if (element.webkitRequestFullscreen) {
        element.webkitRequestFullScreen()
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    6、关闭全屏

    export const exitFullscreen = () => {
      if (document.exitFullscreen) {
        document.exitFullscreen()
      } else if (document.msExitFullscreen) {
        document.msExitFullscreen()
      } else if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen()
      } else if (document.webkitExitFullscreen) {
        document.webkitExitFullscreen()
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    7、大小写转换

    参数:
    // str 待转换的字符串
    // type 1-全大写 2-全小写 3-首字母大写
    
    export const turnCase = (str, type) => {
      switch (type) {
        case 1:
          return str.toUpperCase()
        case 2:
          return str.toLowerCase()
        case 3:
          //return str[0].toUpperCase() + str.substr(1).toLowerCase() // substr 已不推荐使用
          return str[0].toUpperCase() + str.substring(1).toLowerCase()
        default:
          return str
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    实例:

    turnCase('vue', 1) // VUE
    turnCase('REACT', 2) // react
    turnCase('vue', 3) // Vue
    
    
    • 1
    • 2
    • 3
    • 4

    8、解析URL参数

    export const getSearchParams = () => {
      const searchPar = new URLSearchParams(window.location.search)
      const paramsObj = {}
      for (const [key, value] of searchPar.entries()) {
        paramsObj[key] = value
      }
      return paramsObj
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    示例:

    // 假设目前位于 https://****com/index?id=154513&age=18;
    getSearchParams(); // {id: "154513", age: "18"}
    
    • 1
    • 2

    9、判断手机是Andoird还是IOS

    /** 
     * 1: ios
     * 2: android
     * 3: 其它
     */
     export const getOSType=() => {
      let u = navigator.userAgent, app = navigator.appVersion;
      let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1;
      let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
      if (isIOS) {
        return 1;
      }
      if (isAndroid) {
        return 2;
      }
      return 3;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    10、数组对象根据字段去重

    // 参数:
    // arr 要去重的数组
    // key 根据去重的字段名
    export const uniqueArrayObject = (arr = [], key = 'id') => {
      if (arr.length === 0) return
      let list = []
      const map = {}
      arr.forEach((item) => {
        if (!map[item[key]]) {
          map[item[key]] = item
        }
      })
      list = Object.values(map)
    
      return list
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    示例:

    const responseList = [
      { id: 1, name: '树哥' },
      { id: 2, name: '黄老爷' },
      { id: 3, name: '张麻子' },
      { id: 1, name: '黄老爷' },
      { id: 2, name: '张麻子' },
      { id: 3, name: '树哥' },
      { id: 1, name: '树哥' },
      { id: 2, name: '黄老爷' },
      { id: 3, name: '张麻子' },
    ]
    
    uniqueArrayObject(responseList, 'id')
    // [{ id: 1, name: '树哥' },{ id: 2, name: '黄老爷' },{ id: 3, name: '张麻子' }]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    11、滚动到页面顶部

    export const scrollToTop = () => {
      const height = document.documentElement.scrollTop || document.body.scrollTop;
      if (height > 0) {
        window.requestAnimationFrame(scrollToTop);
        window.scrollTo(0, height - height / 8);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    12、滚动到元素位置

    export const smoothScroll = element =>{
      document.querySelector(element).scrollIntoView({
          behavior: 'smooth'
      });
    };
    // 示例:
    smoothScroll('#target'); // 平滑滚动到 ID 为 target 的元素
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    13、uuid

    export const uuid = () => {
      const temp_url = URL.createObjectURL(new Blob())
      const uuid = temp_url.toString()
      URL.revokeObjectURL(temp_url) //释放这个url
      return uuid.substring(uuid.lastIndexOf('/') + 1)
    }
    
    // 实例:
    uuid() // a640be34-689f-4b98-be77-e3972f9bffdd
    // 不过要吐槽一句的是,uuid一般应由后端来进行生成
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    14、金额格式化

    // 参数:
    
    // {number} number:要格式化的数字
    // {number} decimals:保留几位小数
    // {string} dec_point:小数点符号
    // {string} thousands_sep:千分位符号
    
    export const moneyFormat = (number, decimals, dec_point, thousands_sep) => {
      number = (number + '').replace(/[^0-9+-Ee.]/g, '')
      const n = !isFinite(+number) ? 0 : +number
      const prec = !isFinite(+decimals) ? 2 : Math.abs(decimals)
      const sep = typeof thousands_sep === 'undefined' ? ',' : thousands_sep
      const dec = typeof dec_point === 'undefined' ? '.' : dec_point
      let s = ''
      const toFixedFix = function(n, prec) {
        const k = Math.pow(10, prec)
        return '' + Math.ceil(n * k) / k
      }
      s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.')
      const re = /(-?\d+)(\d{3})/
      while (re.test(s[0])) {
        s[0] = s[0].replace(re, '$1' + sep + '$2')
      }
    
      if ((s[1] || '').length < prec) {
        s[1] = s[1] || ''
        s[1] += new Array(prec - s[1].length + 1).join('0')
      }
      return s.join(dec)
    }
    
    // 示例:
    moneyFormat(10000000) // 10,000,000.00
    moneyFormat(10000000, 3, '.', '-') // 10-000-000.000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    15、存储操作

    class MyCache {
      constructor(isLocal = true) {
        this.storage = isLocal ? localStorage : sessionStorage
      }
    
      setItem(key, value) {
        if (typeof (value) === 'object') value = JSON.stringify(value)
        this.storage.setItem(key, value)
      }
    
      getItem(key) {
        try {
          return JSON.parse(this.storage.getItem(key))
        } catch (err) {
          return this.storage.getItem(key)
        }
      }
    
      removeItem(key) {
        this.storage.removeItem(key)
      }
    
      clear() {
        this.storage.clear()
      }
    
      key(index) {
        return this.storage.key(index)
      }
    
      length() {
        return this.storage.length
      }
    }
    
    const localCache = new MyCache()
    const sessionCache = new MyCache(false)
    
    export { localCache, sessionCache }
    
    // 示例:
    localCache.getItem('user')
    sessionCache.setItem('name','树哥')
    sessionCache.getItem('token')
    localCache.clear()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    16、下载文件

    // 参数:
    
    // api 接口
    // params 请求参数
    // fileName 文件名
    
    const downloadFile = (api, params, fileName, type = 'get') => {
      axios({
        method: type,
        url: api,
        responseType: 'blob', 
        params: params
      }).then((res) => {
        let str = res.headers['content-disposition']
        if (!res || !str) {
          return
        }
        let suffix = ''
        // 截取文件名和文件类型
        if (str.lastIndexOf('.')) {
          fileName ? '' : fileName = decodeURI(str.substring(str.indexOf('=') + 1, str.lastIndexOf('.')))
          suffix = str.substring(str.lastIndexOf('.'), str.length)
        }
        //  如果支持微软的文件下载方式(ie10+浏览器)
        if (window.navigator.msSaveBlob) {
          try {
            const blobObject = new Blob([res.data]);
            window.navigator.msSaveBlob(blobObject, fileName + suffix);
          } catch (e) {
            console.log(e);
          }
        } else {
          //  其他浏览器
          let url = window.URL.createObjectURL(res.data)
          let link = document.createElement('a')
          link.style.display = 'none'
          link.href = url
          link.setAttribute('download', fileName + suffix)
          document.body.appendChild(link)
          link.click()
          document.body.removeChild(link)
          window.URL.revokeObjectURL(link.href);
        }
      }).catch((err) => {
        console.log(err.message);
      })
    }
    
    // 示例:
    downloadFile('/api/download', {id}, '文件名')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    17、时间操作

    // 关于时间操作,没必要自己再写一大串代码了,强烈推荐使用 day.js
    
    // Day.js 是一个仅 2kb 大小的轻量级 JavaScript 时间日期处理库,下载、解析和执行的JavaScript更少,为代码留下更多的时间。
    
    • 1
    • 2
    • 3

    18、深拷贝

    export const clone = parent => {
      // 判断类型
      const isType = (obj, type) => {
        if (typeof obj !== "object") return false;
        const typeString = Object.prototype.toString.call(obj);
        let flag;
        switch (type) {
          case "Array":
            flag = typeString === "[object Array]";
            break;
          case "Date":
            flag = typeString === "[object Date]";
            break;
          case "RegExp":
            flag = typeString === "[object RegExp]";
            break;
          default:
            flag = false;
        }
        return flag;
      };
    
      // 处理正则
      const getRegExp = re => {
        var flags = "";
        if (re.global) flags += "g";
        if (re.ignoreCase) flags += "i";
        if (re.multiline) flags += "m";
        return flags;
      };
      // 维护两个储存循环引用的数组
      const parents = [];
      const children = [];
    
      const _clone = parent => {
        if (parent === null) return null;
        if (typeof parent !== "object") return parent;
    
        let child, proto;
    
        if (isType(parent, "Array")) {
          // 对数组做特殊处理
          child = [];
        } else if (isType(parent, "RegExp")) {
          // 对正则对象做特殊处理
          child = new RegExp(parent.source, getRegExp(parent));
          if (parent.lastIndex) child.lastIndex = parent.lastIndex;
        } else if (isType(parent, "Date")) {
          // 对Date对象做特殊处理
          child = new Date(parent.getTime());
        } else {
          // 处理对象原型
          proto = Object.getPrototypeOf(parent);
          // 利用Object.create切断原型链
          child = Object.create(proto);
        }
    
        // 处理循环引用
        const index = parents.indexOf(parent);
    
        if (index != -1) {
          // 如果父数组存在本对象,说明之前已经被引用过,直接返回此对象
          return children[index];
        }
        parents.push(parent);
        children.push(child);
    
        for (let i in parent) {
          // 递归
          child[i] = _clone(parent[i]);
        }
    
        return child;
      };
      return _clone(parent);
    };
    // 此方法存在一定局限性:一些特殊情况没有处理: 例如Buffer对象、Promise、Set、Map。
    // 如果确实想要完备的深拷贝,推荐使用 lodash 中的 cloneDeep 方法。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    19、模糊搜索

    // list 原数组
    // keyWord 查询的关键词
    // attribute 数组需要检索属性
    
    export const fuzzyQuery = (list, keyWord, attribute = 'name') => {
      const reg = new RegExp(keyWord)
      const arr = []
      for (let i = 0; i < list.length; i++) {
        if (reg.test(list[i][attribute])) {
          arr.push(list[i])
        }
      }
      return arr
    }
    // 示例:
    const list = [
      { id: 1, name: '树哥' },
      { id: 2, name: '黄老爷' },
      { id: 3, name: '张麻子' },
      { id: 4, name: '汤师爷' },
      { id: 5, name: '胡万' },
      { id: 6, name: '花姐' },
      { id: 7, name: '小梅' }
    ]
    fuzzyQuery(list, '树', 'name') // [{id: 1, name: '树哥'}]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    20、遍历树节点

    export const foreachTree = (data, callback, childrenName = 'children') => {
      for (let i = 0; i < data.length; i++) {
        callback(data[i])
        if (data[i][childrenName] && data[i][childrenName].length > 0) {
          foreachTree(data[i][childrenName], callback, childrenName)
        }
      }
    }
    
    // 假设我们要从树状结构数据中查找 id 为 9 的节点
    
    const treeData = [{
      id: 1,
      label: '一级 1',
      children: [{
        id: 4,
        label: '二级 1-1',
        children: [{
          id: 9,
          label: '三级 1-1-1'
        }, {
          id: 10,
          label: '三级 1-1-2'
        }]
      }]
     }, {
      id: 2,
      label: '一级 2',
      children: [{
        id: 5,
        label: '二级 2-1'
      }, {
        id: 6,
        label: '二级 2-2'
      }]
      }, {
        id: 3,
        label: '一级 3',
        children: [{
          id: 7,
          label: '二级 3-1'
        }, {
          id: 8,
          label: '二级 3-2'
        }]
    }],
    
    let result
    foreachTree(data, (item) => {
      if (item.id === 9) {
        result = item
      }
    })
    console.log('result', result)  // {id: 9,label: "三级 1-1-1"}  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    数组乱序

    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]];
      }
      return arr;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    数组扁平化

    export const flatten = (arr) => {
      let result = [];
     
      for(let i = 0; i < arr.length; i++) {
        if(Array.isArray(arr[i])) {
          result = result.concat(flatten(arr[i]));
        } else {
          result.push(arr[i]);
        }
      }
      return result;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    数组中获取随机数

    export const sample = arr => arr[Math.floor(Math.random() * arr.length)];
    
    • 1

    生成随机字符串

    export const randomString = (len) => {
      let chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz123456789';
      let strLen = chars.length;
      let randomStr = '';
      for (let i = 0; i < len; i++) {
          randomStr += chars.charAt(Math.floor(Math.random() * strLen));
      }
      return randomStr;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    字符串首字母大写

     export const fistLetterUpper = (str) => {
      return str.charAt(0).toUpperCase() + str.slice(1);
    };
    
    • 1
    • 2
    • 3

    手机号中间四位变成*

    export const telFormat = (tel) => {
      tel = String(tel); 
       return tel.substr(0,3) + "****" + tel.substr(7);
    };
    
    • 1
    • 2
    • 3
    • 4

    驼峰命名转换成短横线命名

    export const getCamelCase = (str) => {
      return str.replace( /-([a-z])/g, (i, item) => item.toUpperCase())
    }
    
    • 1
    • 2
    • 3

    全角转换为半角

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    半角转换为全角

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    数字转化为大写金额

    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][j] + p;
              n = Math.floor(n / 10);
          }
          s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s;
      }
      return s.replace(/(零.)*零元/, '元')
          .replace(/(零.)+/g, '零')
          .replace(/^整$/, '零元整');
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    数字转化为中文数字

    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]] + idxs[len-idx];
         } else {
           let left = len - idx;
           let right = len - idx + $1.length;
           if(Math.floor(right / 4) - Math.floor(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]]
           }
         }
        });
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    存储loalStorage

    export const loalStorageSet = (key, value) => {
      if (!key) return;
      if (typeof value !== 'string') {
          value = JSON.stringify(value);
      }
      window.localStorage.setItem(key, value);
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    获取localStorage

    export const loalStorageGet = (key) => {
      if (!key) return;
      return window.localStorage.getItem(key);
    };
    
    • 1
    • 2
    • 3
    • 4

    删除localStorage

    export const loalStorageRemove = (key) => {
      if (!key) return;
      window.localStorage.removeItem(key);
    };
    
    • 1
    • 2
    • 3
    • 4

    存储sessionStorage

    export const sessionStorageSet = (key, value) => {
      if (!key) return;
       if (typeof value !== 'string') {
         value = JSON.stringify(value);
       }
       window.sessionStorage.setItem(key, value)
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    获取sessionStorage

    export const sessionStorageGet = (key) => {
      if (!key) return;
       return window.sessionStorage.getItem(key)
    };
    
    • 1
    • 2
    • 3
    • 4

    删除sessionStorage

    export const sessionStorageRemove = (key) => {
      if (!key) return;
       window.sessionStorage.removeItem(key)
    };
    
    • 1
    • 2
    • 3
    • 4

    操作cookie

    设置cookie
    export const setCookie = (key, value, expire) => {
      const d = new Date();
      d.setDate(d.getDate() + expire);
      document.cookie = `${key}=${value};expires=${d.toUTCString()}`
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5

    读取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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    删除cookie

    export const delCookie = (key) => {
      document.cookie = `${encodeURIComponent(key)}=;expires=${new Date()}`
    };
    
    • 1
    • 2
    • 3

    校验身份证号码

    export const checkCardNo = (value) => {
      let reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
      return reg.test(value);
    };
    
    • 1
    • 2
    • 3
    • 4

    校验是否包含中文

    export const haveCNChars => (value) => {
      return /[\u4e00-\u9fa5]/.test(value);
    }
    
    • 1
    • 2
    • 3

    校验是否为中国大陆的邮政编码

    export const isPostCode = (value) => {
      return /^[1-9][0-9]{5}$/.test(value.toString());
    }
    
    • 1
    • 2
    • 3

    校验是否为IPv6地址

    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
    • 2
    • 3

    校验是否为邮箱地址

    export const isEmail = (value)=> {
      return /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/.test(value);
    }
    
    • 1
    • 2
    • 3

    校验是否为中国大陆手机号

    export const isTel = (value) => {
      return /^1[3,4,5,6,7,8,9][0-9]{9}$/.test(value.toString());
    }
    
    • 1
    • 2
    • 3

    校验是否包含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) {
               if (value.length > 1) {
                   const ls = value.charCodeAt(i + 1);
                   const uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
                   if (0x1d000 <= uc && uc <= 0x1f77f) {
                       return true;
                   }
               }
           } else if (value.length > 1) {
               const ls = value.charCodeAt(i + 1);
               if (ls == 0x20e3) {
                   return true;
               }
           } else {
               if (0x2100 <= hs && hs <= 0x27ff) {
                   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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    操作URL

    获取URL参数列表

    export const GetRequest = () => {
      let url = location.search;
      const paramsStr = /.+\?(.+)$/.exec(url)[1]; // 将 ? 后面的字符串取出来
      const paramsArr = paramsStr.split('&'); // 将字符串以 & 分割后存到数组中
      let paramsObj = {};
      // 将 params 存到对象中
      paramsArr.forEach(param => {
        if (/=/.test(param)) { // 处理有 value 的参数
          let [key, val] = param.split('='); // 分割 key 和 value
          val = decodeURIComponent(val); // 解码
          val = /^\d+$/.test(val) ? parseFloat(val) : val; // 判断是否转为数字
          if (paramsObj.hasOwnProperty(key)) { // 如果对象有 key,则添加一个值
            paramsObj[key] = [].concat(paramsObj[key], val);
          } else { // 如果对象没有这个 key,创建 key 并设置值
            paramsObj[key] = val;
          }
        } else { // 处理没有 value 的参数
          paramsObj[param] = true;
        }
      })
      return paramsObj;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    检测URL是否有效

    export const getUrlState = (URL) => {
      let xmlhttp = new ActiveXObject("microsoft.xmlhttp");
      xmlhttp.Open("GET", URL, false);
      try {
        xmlhttp.Send();
      } catch (e) {
      } finally {
        let result = xmlhttp.responseText;
        if (result) {
          if (xmlhttp.Status == 200) {
            return true;
          } else {
            return false;
          }
        } else {
          return false;
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    键值对拼接成URL参数

    export const params2Url = (obj) => {
      let params = []
      for (let key in obj) {
        params.push(`${key}=${obj[key]}`);
      }
      return encodeURIComponent(params.join('&'))
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    修改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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    删除URL中指定参数

    export const funcUrlDel = (name) => {
      const baseUrl = location.origin + location.pathname + "?";
      const query = location.search.substr(1);
      if (query.indexOf(name) > -1) {
        const obj = {};
        const arr = query.split("&");
        for (let i = 0; i < arr.length; i++) {
          arr[i] = arr[i].split("=");
          obj[arr[i][0]] = arr[i][1];
        }
        delete obj[name];
        return baseUrl + JSON.stringify(obj).replace(/[\"\{\}]/g,"").replace(/\:/g,"=").replace(/\,/g,"&");
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    设备判断

    判断是移动还是PC设备
    export const isMobile = () => {
      if ((navigator.userAgent.match(/(iPhone|iPod|Android|ios|iOS|iPad|Backerry|WebOS|Symbian|Windows Phone|Phone)/i))) {
      return 'mobile';
      }
      return 'desktop';
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    判断是否是苹果还是安卓移动设备

    export const isAppleMobileDevice = () => {
      let reg = /iphone|ipod|ipad|Macintosh/i;
      return reg.test(navigator.userAgent.toLowerCase());
    }
    
    • 1
    • 2
    • 3
    • 4

    判断是否是安卓移动设备

    export const isAndroidMobileDevice = () => {
      return /android/i.test(navigator.userAgent.toLowerCase());
    }
    
    • 1
    • 2
    • 3

    判断是Windows还是Mac系统

    export const osType = () => {
      const agent = navigator.userAgent.toLowerCase();
      const isMac = /macintosh|mac os x/i.test(navigator.userAgent);
     const isWindows = agent.indexOf("win64") >= 0 || agent.indexOf("wow64") >= 0 || agent.indexOf("win32") >= 0 || agent.indexOf("wow32") >= 0;
      if (isWindows) {
          return "windows";
      }
      if(isMac){
          return "mac";
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    判断是否是微信/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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    浏览器型号和版本

    export const getExplorerInfo = () => {
      let t = navigator.userAgent.toLowerCase();
      return 0 <= t.indexOf("msie") ? { //ie < 11
          type: "IE",
          version: Number(t.match(/msie ([\d]+)/)[1])
      } : !!t.match(/trident\/.+?rv:(([\d.]+))/) ? { // ie 11
          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: "Chrome",
          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(/version\/([\d]+)/)[1])
      } : {
          type: t,
          version: -1
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    滚动到页面底部

    export const scrollToBottom = () => {
      window.scrollTo(0, document.documentElement.clientHeight);  
    }
    
    • 1
    • 2
    • 3

    获取可视窗口高度

    export const getClientHeight = () => {
      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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    获取可视窗口宽度

    export const getPageViewWidth = () => {
      return (document.compatMode == "BackCompat" ? document.body : document.documentElement).clientWidth;
    }
    
    • 1
    • 2
    • 3

    时间操作

    // 当前时间
    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.getMinutes() : ('0' + now.getMinutes());
      const sec = now.getSeconds() >= 10 ? now.getSeconds() : ('0' + now.getSeconds());
      return +year + "年" + (month + 1) + "月" + date + "日 " + hour + ":" + miu + ":" + sec;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    格式化时间

    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' : '') + m)
          .replace(/ss/g,(s<10 ? '0' : '') + s)
    }
    // dateFormater('YYYY-MM-DD HH:mm:ss')
    // dateFormater('YYYYMMDDHHmmss')
    
    // JavaScript操作
    // 阻止冒泡事件
    export const stopPropagation = (e) => { 
      e = e || window.event; 
      if(e.stopPropagation) {    // W3C阻止冒泡方法 
          e.stopPropagation(); 
      } else { 
          e.cancelBubble = true; // IE阻止冒泡方法 
      } 
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    数据类型判断

    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("").toLowerCase();
      } else {
        // 判断数据是基本数据类型的情况和函数的情况
        return typeof value;
      }
    }
    
    // console.log(getType(0))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    对象深拷贝

    export const deepClone = (obj, hash = new WeakMap()) => {
      // 日期对象直接返回一个新的日期对象
      if (obj instanceof Date){
       return new Date(obj);
      } 
      //正则对象直接返回一个新的正则对象     
      if (obj instanceof RegExp){
       return new RegExp(obj);     
      }
      //如果循环引用,就用 weakMap 来解决
      if (hash.has(obj)){
       return hash.get(obj);
      }
      // 获取对象所有自身属性的描述
      let allDesc = Object.getOwnPropertyDescriptors(obj);
      // 遍历传入参数所有键的特性
      let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc)
      
      hash.set(obj, cloneObj)
      for (let key of Reflect.ownKeys(obj)) { 
        if(typeof obj[key] === 'object' && obj[key] !== null){
         cloneObj[key] = deepClone(obj[key], hash);
        } else {
         cloneObj[key] = obj[key];
        }
      }
      return cloneObj
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    计算字符串长度 calculateStrLengh

    计算字符长度(一个汉字2个字符)

    function calculateStrLengh(str){
    	var len=0;
    	if(!isExist(str)){
    		return 0;
    	}
    	for (var i=0; i<str.length; i++) {
    		var c = str.charCodeAt(i);
    		//单字节加1
    		if ((c >= 0x0001 && c <= 0x007e) || (0xff60<=c && c<=0xff9f)) {
    			len++;
    		}
    		else {
    			len+=2;
    		}
    	}
    	return len;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    获取小程序链接的地址栏参数 GetWxMiniProgramUrlParam

    // 判断是否为IE8
    var DEFAULT_VERSION = 8.0;
    var ua = navigator.userAgent.toLowerCase();
    var isIE = ua.indexOf("msie") > -1;
    var safariVersion;
    if (isIE) {
    	safariVersion = ua.match(/msie ([\d.]+)/)[1];
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    使用 vscode 插件可视化制作和管理脚手架及原理解析
    c++最小步数模型(魔板)
    【数据分享】2010-2020年全球民航交通流量数据
    ArrayList集合特点为什么是增删慢、查询快?
    10_创建和管理表
    一个web请求在springboot经历了什么
    Python爬虫之Js逆向案例(6)-有道翻译
    3. HTML的语法规范
    剑指 Offer 13. 机器人的运动范围
    Git 客户端可视化工具tortoisegit
  • 原文地址:https://blog.csdn.net/qxfjyk/article/details/134534335