常用的JS函数封装

163 阅读1分钟

函数节流

    /**
     * @Author: hongzxiang
     * @description: 节流函数
     * @param {*} fn 函数
     * @param {*} interval 多久执行一次
     * @param {*} leading 初始化后是否立即加载
     */
    const throttle = function (fn, interval, leading = true) {
      let nowTime
      let lastTime = 0
      function _throttle(...args) {
        nowTime = new Date().getTime()
        // leading为flase表示不希望立即执行函数
        // lastTime为0表示函数没执行过
        if (!leading && lastTime === 0) {
          lastTime = nowTime
        }

        if (nowTime - lastTime > interval) {
          fn.apply(this, args)
          lastTime = nowTime
        }
      }
      return _throttle
    },

函数防抖

const debounce = function(func, wait, immediate) { //函数防抖[func 函数,wait 延迟执行毫秒数,immediate true 表立即执行,false 表非立即执行,立即执行是触发事件后函数会立即执行,然后n秒内不触发事件才能继续执行函数的效果]
  let timeout;
  return function() {
    let context = this;
    let args = arguments;
    if (timeout) clearTimeout(timeout);
    if (immediate) {
      var callNow = !timeout;
      timeout = setTimeout(() => {
        timeout = null;
      }, wait)
      if (callNow) func.apply(context, args)
    } else {
      timeout = setTimeout(function() {
        func.apply(context, args)
      }, wait);
    }
  }
}

获取url参数

const getUrlParam = function(name) { // 获取url参数
  let reg = new RegExp('(^|&?)' + name + '=([^&]*)(&|$)', 'i')
  let r = window.location.href.substr(1).match(reg)
  if (r != null) {
    return decodeURI(r[2])
  }
  return undefined
}

判断浏览器是否开启无痕模式

const isLocalStorage = function(name) {
  if(window.Storage && window.localStorage && window.localStorage instanceof Storage) return true
  else return false
}

本地存储封装

const store = { // 本地存储
  set: function(name, value, day) { // 设置
    let d = new Date()
    let time = 0
    day = (typeof(day) === 'undefined' || !day) ? 1 : day // 时间,默认存储1天
    time = d.setHours(d.getHours() + (24 * day)) // 毫秒
    localStorage.setItem(name, JSON.stringify({
      data: value,
      time: time
    }))
  },
  get: function(name) { // 获取
    let data = localStorage.getItem(name)
    if (!data) {
      return null
    }
    let obj = JSON.parse(data)
    if (new Date().getTime() > obj.time) { // 过期
      localStorage.removeItem(name)
      return null
    } else {
      return obj.data
    }
  },
  clear: function(name) { // 清空
    if (name) { // 删除键为name的缓存
      localStorage.removeItem(name)
    } else { // 清空全部
      localStorage.clear()
    }
  }
}

cookie操作【set,get,del】

const cookie = { // cookie操作【set,get,del】
  set: function(name, value, day) {
    let oDate = new Date()
    oDate.setDate(oDate.getDate() + (day || 30))
    document.cookie = name + '=' + value + ';expires=' + oDate + "; path=/;"
  },
  get: function(name) {
    let str = document.cookie
    let arr = str.split('; ')
    for (let i = 0; i < arr.length; i++) {
      let newArr = arr[i].split('=')
      if (newArr[0] === name) {
        return newArr[1]
      }
    }
  },
  del: function(name) {
    this.set(name, '', -1)
  }
}

时间格式化

const formatDate = function(fmt, date) { // 时间格式化 【'yyyy-MM-dd hh:mm:ss',时间】
  if (typeof date !== 'object') {
    date = !date ? new Date() : new Date(date)
  }
  var o = {
    'M+': date.getMonth() + 1, // 月份
    'd+': date.getDate(), // 日
    'h+': date.getHours(), // 小时
    'm+': date.getMinutes(), // 分
    's+': date.getSeconds(), // 秒
    'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
    'S': date.getMilliseconds() // 毫秒
  }
  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
  }
  for (var k in o) {
    if (new RegExp('(' + k + ')').test(fmt)) {
      fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
    }
  }
  return fmt
}

封装一个原生ajax请求

const ajax = function(conf) { // ajax操作
  let url = conf.url,
    data = conf.data,
    senData = [], // 封装后的数据
    async = conf.async !== undefined ? conf.async : true, // ture为异步请求
      type = conf.type || 'get', // 默认请求方式get
      dataType = conf.dataType || 'json',
      contenType = conf.contenType || 'application/x-www-form-urlencoded',
      success = conf.success,
      error = conf.error,
      isForm = conf.isForm || false, // 是否formdata
      header = conf.header || {}, // 头部信息
      xhr = '' // 创建ajax引擎对象
  if (data == null) {
    senData = ''
  } else if (typeof data === 'object' && !isForm) { // 如果data是对象,转换为字符串
    for (var k in data) {
      senData.push(encodeURIComponent(k) + '=' + encodeURIComponent(data[k]))
    }
    senData = senData.join('&')
  } else {
    senData = data
  }
  try {
    xhr = new ActiveXObject('microsoft.xmlhttp') // IE内核系列浏览器
  } catch (e1) {
    try {
      xhr = new XMLHttpRequest() // 非IE内核浏览器
    } catch (e2) {
      if (error != null) {
        error('不支持ajax请求')
      }
    }
  };
  xhr.open(type, type !== 'get' ? url : url + '?' + senData, async)
  if (type !== 'get' && !isForm) {
    xhr.setRequestHeader('content-type', contenType)
  }
  for (var h in header) {
    xhr.setRequestHeader(h, header[h])
  }
  xhr.send(type !== 'get' ? senData : null)
  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
      if (xhr.status >= 200 && xhr.status < 300) {
        if (dataType === 'json' && success != null) {
          let res = ''
          try {
            res = eval('(' + xhr.responseText + ')')
          } catch (e) {
            console.log(e)
          }
          success(res) // 将json字符串转换为js对象
        };
      } else {
        if (error != null) {
          error('链接失败!' + xhr.status)
        }
      }
    }
  }
}

设备判断 【web、android、ios】

const isDevice = function() { // 判断是android还是ios还是web
  var ua = navigator.userAgent.toLowerCase()
  if (ua.match(/iPhone\sOS/i) === 'iphone os' || ua.match(/iPad/i) === 'ipad') { // ios
    return 'iOS'
  }
  if (ua.match(/Android/i) === 'android') {
    return 'Android'
  }
  return 'Web'
}

判断是否为微信

const isWx = function() { // 判断是否为微信
  var ua = window.navigator.userAgent.toLowerCase()
  if (ua.match(/MicroMessenger/i) === 'micromessenger') {
    return true
  }
  return false
}

图片地址转base64

const getBase64 = function(img) { //传入图片路径,返回base64,使用getBase64(url).then(function(base64){},function(err){}); 
  let getBase64Image = function(img, width, height) { //width、height调用时传入具体像素值,控制大小,不传则默认图像大小
    let canvas = document.createElement("canvas");
    canvas.width = width ? width : img.width;
    canvas.height = height ? height : img.height;
    let ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
    let dataURL = canvas.toDataURL();
    return dataURL;
  }
  let image = new Image();
  image.crossOrigin = '';
  image.src = img;
  let deferred = $.Deferred();
  if (img) {
    image.onload = function() {
      deferred.resolve(getBase64Image(image));
    }
    return deferred.promise();
  }
}

url参数转换为对象

const parseQueryString = function(url) { //url参数转对象
  url = !url ? window.location.href : url;
  if (url.indexOf('?') === -1) {
    return {};
  }
  let search = url[0] === '?' ? url.substr(1) : url.substring(url.lastIndexOf('?') + 1);
  if (search === '') {
    return {};
  }
  search = search.split('&');
  let query = {};
  for (let i = 0; i < search.length; i++) {
    let pair = search[i].split('=');
    query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || '');
  }
  return query;
}

对象序列化

const stringfyQueryString = function(obj) { //对象序列化【对象转url参数】
  if (!obj) return '';
  let pairs = [];
  for (let key in obj) {
    let value = obj[key];
    if (value instanceof Array) {
      for (let i = 0; i < value.length; ++i) {
        pairs.push(encodeURIComponent(key + '[' + i + ']') + '=' + encodeURIComponent(value[i]));
      }
      continue;
    }
    pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]));
  }
  return pairs.join('&');
}

字符串大小写转换

const changeCase = function(str, type) { 
  // 字符串大小写转换 type:  1:首字母大写  2:首字母小写  3:大小写转换  4:全部大写  5:全部小写
  type = type || 4
  switch (type) {
    case 1:
      return str.replace(/\b\w+\b/g, function(word) {
        return word.substring(0, 1).toUpperCase() + word.substring(1).toLowerCase()
      })
    case 2:
      return str.replace(/\b\w+\b/g, function(word) {
        return word.substring(0, 1).toLowerCase() + word.substring(1).toUpperCase()
      })
    case 3:
      return str.split('').map(function(word) {
        if (/[a-z]/.test(word)) {
          return word.toUpperCase()
        } else {
          return word.toLowerCase()
        }
      }).join('')
    case 4:
      return str.toUpperCase()
    case 5:
      return str.toLowerCase()
    default:
      return str
  }
}

去除字符串空格

const trim = function(str, type) { 
  // 去除空格, type:  1-所有空格  2-前后空格  3-前空格 4-后空格
  type = type || 1
  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
  }
}

常用的正则验证

const checkStr = function(str, type) { // 常用正则验证,注意type大小写
  switch (type) {
    case 'phone': // 手机号码
      return /^1[3|4|5|6|7|8|9][0-9]{9}$/.test(str)
    case 'tel': // 座机
      return /^(0\d{2,3}-\d{7,8})(-\d{1,4})?$/.test(str)
    case 'card': // 身份证
      return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(str)
    case 'pwd': // 密码以字母开头,长度在6~18之间,只能包含字母、数字和下划线
      return /^[a-zA-Z]\w{5,17}$/.test(str)
    case 'postal': // 邮政编码
      return /[1-9]\d{5}(?!\d)/.test(str)
    case 'QQ': // QQ号
      return /^[1-9][0-9]{4,9}$/.test(str)
    case 'email': // 邮箱
      return /^[\w-]+(.[\w-]+)*@[\w-]+(.[\w-]+)+$/.test(str)
    case 'money': // 金额(小数点2位)
      return /^\d*(?:.\d{0,2})?$/.test(str)
    case 'URL': // 网址
      return /(http|ftp|https)://[\w-_]+(.[\w-_]+)+([\w-.,@?^=%&:/~+#]*[\w-@?^=%&/~+#])?/.test(str)
    case 'IP': // IP
      return /((?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d))/.test(str)
    case 'date': // 日期时间
      return /^(\d{4})-(\d{2})-(\d{2}) (\d{2})(?::\d{2}|:(\d{2}):(\d{2}))$/.test(str) ||
        /^(\d{4})-(\d{2})-(\d{2})$/.test(str)
    case 'number': // 数字
      return /^[0-9]$/.test(str)
    case 'english': // 英文
      return /^[a-zA-Z]+$/.test(str)
    case 'chinese': // 中文
      return /^[\u4E00-\u9FA5]+$/.test(str)
    case 'lower': // 小写
      return /^[a-z]+$/.test(str)
    case 'upper': // 大写
      return /^[A-Z]+$/.test(str)
    case 'HTML': // HTML标记
      return /<("[^"]*"|'[^']*'|[^'">])*>/.test(str)
    default:
      return true
  }
}

时间与时间戳转换

const stamp = { // 时间,时间戳转换
  getTime: function(time) { // 时间转10位时间戳
    let date = time ? new Date(time.replace(/-/g, '/')) : new Date()
    return Math.round(date.getTime() / 1000)
  },
  timeToStr: function(time, fmt) { // 10位时间戳转时间
    return new Date(time * 1000).pattern(fmt || 'yyyy-MM-dd')
  }
}

简易深拷贝

const deepClone = function(obj) {
  function isObject(o) {
    return (typeof o === 'object' || typeof o === 'function') && o !== null;
  }
  if(!isObject(obj)) {
    return obj
  }
  let isArray = Array.isArray(obj);
  let newObj = isArray ? [...obj] : {...obj};
  // Reflect 是一个内置的对象,它提供拦截 JavaScript 操作的方法
   Reflect.ownKeys(newObj).forEach(key => {
    newObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
  })
  return newObj;
}