前端公用 util.js

// 高性能数组去重——利用对象的属性不会重复这一特性
function distinct(a, b) {
    let arr = a.concat(b)
    let result = []
    let obj = {}
 
    for (let i of arr) {
        if (!obj[i]) {
            result.push(i)
            obj[i] = 1
        }
    }
    return result
}

/**
 * 防抖
 * @param fn            高频函数(要执行的函数)
 * @param wait          延时时间,毫秒
 * @param immediate     前置执行/后置执行,默认后置执行(false)
 */
export const debounce = (fn, wait, immediate) => {
  let timer
  return function () {
    if (timer) clearTimeout(timer)
    if (immediate) {
      // 前置执行
      // 如果已经执行过,不再执行
      const callNow = !timer
      timer = setTimeout(() => {
        timer = null
      }, wait)
      if (callNow) {
        fn.apply(this, arguments)
      }
    } else {
      // 后置执行
      timer = setTimeout(() => {
        fn.apply(this, arguments)
      }, wait)
    }
  }
}

/*
 * 数组扁平化
 * @param arr        多维数组
 * @returns {[]}     一维数组
 */
function flatten(arr) {
    let result = []
	if (Array.isArray(arr)) {
        for (let item of arr) {
            if (item.children?.length) {
                const item2 = JSON.parse(JSON.stringify(item))
                delete item2.children
                result.push(item2)
                result = result.concat(flatten(item.children))
            } else {
                    result.push(item)
            }
        }
	}
    return result
}

// 深拷贝(递归实现)
function  deepClone(data) {
    const type = Object.prototype.toString.call(data);
    let obj;
    if (type === '[object Array]') {
        obj = [];
    } else if (type === '[object Object]') {
        obj = {};
    } else {
        // 不再具有下一层次
        return data;
    }
    if (type === '[object Array]') {
        for (let i = 0, len = data.length; i < len; i++) {
            obj.push(this.deepClone(data[i]));
        }
    } else if (type === '[object Object]') {
        // 对原型上的方法也拷贝了....
        for (const key in data) {
            obj[key] = this.deepClone(data[key]);
        }
    }
    return obj;
}

/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string}
 */
function parseTime(time, cFormat) {
  if (arguments.length === 0) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
      time = parseInt(time)
    }
    if ((typeof time === 'number') && (time.toString().length === 10)) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] }
    if (result.length > 0 && value < 10) {
      value = '0' + value
    }
    return value || 0
  })
  return time_str
}

/**
 * @param {number} time
 * @param {string} option
 * @returns {string}
 */
function formatTime(time, option) {
  if (('' + time).length === 10) {
    time = parseInt(time) * 1000
  } else {
    time = +time
  }
  const d = new Date(time)
  const now = Date.now()

  const diff = (now - d) / 1000

  if (diff < 30) {
    return '刚刚'
  } else if (diff < 3600) {
    // less 1 hour
    return Math.ceil(diff / 60) + '分钟前'
  } else if (diff < 3600 * 24) {
    return Math.ceil(diff / 3600) + '小时前'
  } else if (diff < 3600 * 24 * 2) {
    return '1天前'
  }
  if (option) {
    return parseTime(time, option)
  } else {
    return (
      d.getMonth() +
      1 +
      '月' +
      d.getDate() +
      '日' +
      d.getHours() +
      '时' +
      d.getMinutes() +
      '分'
    )
  }
}

/** 获取存储空间大小
 * @param fileSize
 */
function getFileShowSize(fileSize) {
  if (fileSize) {
    var KLength = 1024
    var MLength = KLength * 1024
    var GLength = MLength * 1024
    var TLength = GLength * 1024

    var showStr = ''
    var T = 0
    var G = 0
    var M = 0
    var K = 0
    T = fileSize / TLength
    G = fileSize / GLength
    M = fileSize / MLength

    T = parseInt(T.toFixed(2))
    G = parseInt(G.toFixed(2))
    M = parseInt(M.toFixed(2))

    if (T > 0) {
      // 如果大于1T则显示为2.34TB样式
      T = fileSize / TLength
      showStr = T.toFixed(2) + 'TB'
    } else if (G > 0) {
      // 如果大于1G则显示为2.34GB样式
      G = fileSize / GLength
      showStr = G.toFixed(2) + 'GB'
    } else if (M > 0) {
      // 如果大于1M则显示为2.34MB样式
      M = fileSize / MLength
      showStr = M.toFixed(2) + 'MB'
    } else {
      // 显示为44KB
      K = fileSize / KLength
      if (parseInt(K)) {
        showStr = parseInt(K) + 'KB'
      } else {
        showStr = '--'
      }
    }
    return showStr
  } else {
    return '--'
  }
}

//阻止冒泡
function stopBubble (e) {
  //如果提供了事件对象,则这是一个非IE浏览器
  if ( e && e.stopPropagation ) {
    //因此它支持W3C的stopPropagation()方法
    e.stopPropagation();
  }
  else {
    //否则,我们需要使用IE的方式来取消事件冒泡
    window.event.cancelBubble = true;
  }
}

//阻止浏览器的默认行为
function stopDefault ( e ) {
  //防止浏览器默认行为(W3C)
  if(e && e.preventDefault){
    e.preventDefault();
  }
  //IE中组织浏览器行为
  else{
    window.event.returnValue=false;
    return false;
  }
}

// 文件下载
function downloadFile (url) {
  var $form = $('<form method="GET"></form>');
  $form.attr('action', url);
  $form.appendTo($('body'));
  $form.submit();
  $form.remove();
}

// js 根据文件大小换算合适单位,并保留两位小数
function getFileSize (fileByte) {
  var fileSizeByte = fileByte;
  var fileSizeMsg = "";
  if (fileSizeByte < 1048576) fileSizeMsg = (fileSizeByte / 1024).toFixed(2) + "KB";
  else if (fileSizeByte == 1048576) fileSizeMsg = "1MB";
  else if (fileSizeByte > 1048576 && fileSizeByte < 1073741824) fileSizeMsg = (fileSizeByte / (1024 * 1024)).toFixed(2) + "MB";
  return fileSizeMsg;
}

//用正则表达式实现html转码
function htmlEncodeByRegExp (str){
  if(!str) return "";
  var s = "";
  s = str.replace(/&/g,"&amp;");
  s = s.replace(/</g,"&lt;");
  s = s.replace(/>/g,"&gt;");
  s = s.replace(/ /g,"&nbsp;");
  s = s.replace(/\'/g,"&#39;");
  s = s.replace(/\"/g,"&quot;");
  return s;
}

//用正则表达式实现title换行
function titleBrByRegExp (str){
  if(!str) return "";
  var s = "";
  s = str.replace(/<br>/g,"&#13");
  s = s.replace(/<br\/>/g,"&#13;");
  s = s.replace(/<br \/>/g,"&#13;");
  return s;
}

/**
 * 获取光标位置函数
 * @param obj   input或者textarea对象
 * @returns {number}  获取到的光标位置
 */
function getCursortPosition (obj) {
  var CaretPos = 0; // IE Support
  if (document.selection) {
    obj.focus ();
    var Sel = document.selection.createRange ();
    Sel.moveStart ('character', -obj.value.length);
    CaretPos = Sel.text.length;
  }
  // Firefox support
  else if (obj.selectionStart || obj.selectionStart == '0')
    CaretPos = obj.selectionStart;
  return (CaretPos);
}

/**
 * 设置光标位置函数
 * @param obj   input或者textarea对象
 * @param pos   光标要移动到的位置
 */
function setCaretPosition (obj, pos){
  if(obj.setSelectionRange)
  {
    obj.focus();
    obj.setSelectionRange(pos,pos);
  }
  else if (obj.createTextRange) {
    var range = ctrl.createTextRange();
    range.collapse(true);
    range.moveEnd('character', pos);
    range.moveStart('character', pos);
    range.select();
  }
}
/**
 * 字符串固定位置插入字符
 * @soure       原字符串
 * @start       要插入字符的位置
 * @newStr      要插入的字符
 * @returns {string}
 */
function insertStr(soure, start, newStr){
   return soure.slice(0, start) + newStr + soure.slice(start);
}

// 获取时区
function timeZone() {
  let time = 0 - new Date().getTimezoneOffset() / 60
  if (parseInt(time) === time) {
    return time > -1 ? `UTC+${time}` : `UTC${time}`
  } else {
    const num = `${time}`
    const last = Number(num.substring(num.indexOf('.') + 1, num.length)) * 6
    if (parseInt(time) > 0 && parseInt(time) < 10) {
      time = `0${parseInt(time)}`
    } else if (parseInt(time) > 0 && parseInt(time) > 9) {
      time = parseInt(time)
    } else if (parseInt(time) < 0 && parseInt(time) > -10) {
      time = `-0${Math.abs(parseInt(time))}`
    } else if (parseInt(time) < 0 && parseInt(time) < -9) {
      time = parseInt(time)
    }
    time = `${time}${last}`
    return Number(time) > -1 ? `UTC+${time}` : `UTC${time}`
  }
}

// 获取一个字符串值在指定字符串第n次出现的位置
const findIndex = (str, cha, num) => {
  let index = str.indexOf(cha);
  for(let i = 0; i < num - 1; i++){
    index = str.indexOf(cha, index + 1);
  }
  return index;
}
const str = ‘Hello World!’
findIndex(str, 'o', 2) // 7


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

__畫戟__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值