JavaScript 工具函数(分享)

1. 任意区间的的随机数

/**
 * 任意区间的的随机数
 * @param {Number} max 最大值
 * @param {Number} min 最小值
 * @returns {Number}
 */
const getRandom = (max, min) => Math.floor(Math.random() * (max - min + 1) + min);

2. 判断一个数是不是质数

/**
 * 判断一个数是不是质数
 * @param {Number} num
 * @returns {Boolean} true:是质数、false:不是质数
 */
function isPrime(num) {
  let temp = Math.floor(Math.sqrt(num));
  for (let i = 2; i <= temp; i++) {
    if (num % i == 0) {
      return false;
    }
  }
  return true;
}

3. 传入指定 key 返回当前页面 search 的 value,也可以手动传入url

/**
 * 传入指定 key 返回当前页面 search 的 value,也可以手动传入url
 * @param {Number} key
 * @param {String} url
 * @returns {String}
 */
function getSearch(key, url = "") {
  let search = url.split("?")[1] || location.search.substring(1);
  let obj = {};
  search.split("&").forEach((item) => {
    let temp = item.split("=");
    obj[temp[0]] = temp[1];
  });
  return obj[key];
}

4. 在 Date 上封装了一个返回指定格式的方法

/**
 * 在 Date 上封装了一个返回指定格式的方法
 * @param {String | Number} type 需要分割的类型,需要传入字符,0 为特殊类型(年月日)
 * @param {Number} date 时间戳
 * @returns {String}
 */
Date.format = function (type = "-", date) {
  date = date && new Date(date);
  let time = date || new this();
  let y = time.getFullYear();
  let M = time.getMonth() + 1;
  let d = time.getDate();
  let h = time.getHours();
  let m = time.getMinutes();
  let s = time.getSeconds();

  M = M > 9 ? M : "0" + M;
  d = d > 9 ? d : "0" + d;
  h = h > 9 ? h : "0" + h;
  m = m > 9 ? m : "0" + m;
  s = s > 9 ? s : "0" + s;

  if (type === 0) {
    return `${y}${M}${d}${h}${m}${s}`;
  }

  return `${y}${type}${M}${type}${d} ${h}${type}${m}${type}${s}`;
};

5. 数组去重

/**
 * 数组去重
 * @param {Array} arr
 * @returns {Array}
 */
const toRepeat = (arr) => [...new Set(arr)];

6. 预览pdf,后端返回的文件流设置的只能下载,需要预览

/**
 * 预览Pdf,后端返回的文件流设置的只能下载,需要预览
 * @param {String} url
 */
function previewPdf(url) {
  $.ajax({
    cache: true,
    type: "GET",
    url, //pdf文件流的请求接口
    async: false,
    mimeType: "text/plain; charset=x-user-defined", //jq ajax请求文件流的方式  (起作用的重点)
    success(data) {
      var rawLength = data.length;
      var array = new Uint8Array(new ArrayBuffer(rawLength));
      for (let i = 0; i < rawLength; i++) {
        array[i] = data.charCodeAt(i) & 0xff;
      }
      //上面是把后台请求到的文件流进行转化为符合的流
      var blob = new Blob([array], { type: "application/pdf;charset-UTF-8" });
      var href = URL.createObjectURL(blob);
      open(href);
      URL.revokeObjectURL(href);
    },
    error() {
      alert("网络原因请求失败!");
    },
  });
}

7. 下载pdf,后端返回的文件流,需要下载

/**
 * 下载Pdf,后端返回的文件流,需要下载
 * @param {String} url
 */
function downloadPdf(url) {
  $.ajax({
    type: "POST",
    url,
    headers: {
      "Content-Type": "application/json",
    },
    // 其他类型需要设置 responseType 指定响应的数据类型,默认为json
    xhrFields: { responseType: "blob" },
    data: JSON.stringify({ projectId: null }),
    success: (res) => {
      const blob = new Blob([res], {
        type: "application/pdf",
      });
      let a = document.createElement("a");
      a.download = "demo.pdf";
      a.href = URL.createObjectURL(blob);
      a.click();
      URL.revokeObjectURL(href);
    },
    error() {
      alert("网络原因请求失败!");
    },
  });
}

8. 为元素添加拖拽功能,通过 transform 改变的位置

/**
 * 为元素添加拖拽功能,通过transform改变的位置
 * @param {Element} el
 */
function elDrag(el) {
  let initX = null;
  let initY = null;
  el.style.cursor = "move"; //设置鼠标样式为移动
  // 获取初始点击的位置
  el.addEventListener("mousedown", function (e) {
    // 获取盒子距离可视宽度的距离
    let curX = 0;
    let curY = 0;
    let str = el.style.transform.trim();
    if (str) {
      let reg = /\-?\d+/g;
      curX = Number(reg.exec(str));
      curY = Number(reg.exec(str));
    }
    initX = e.pageX - curX;
    initY = e.pageY - curY;
    // 鼠标移动事件设置移动位置
    document.addEventListener("mousemove", moveEle);
  });
  // 设置当前位置
  function moveEle(e) {
    let x = e.pageX - initX;
    let y = e.pageY - initY;
    el.style.transform = `translate(${x}px,${y}px)`;
  }
  // 鼠标松开移出方法
  document.addEventListener("mouseup", function () {
    document.removeEventListener("mousemove", moveEle);
  });
}

9. 树结构转数组,通过id和pid关联

/**
 * 树结构转数组,通过id和pid关联
 * @param {Array} tree 树结构数组
 * @param {String} child 存放子元素的字段,默认为 children
 * @returns {Array}
 */
function treeToArr(tree, child = "children") {
  let arr = JSON.parse(JSON.stringify(tree));
  while (arr.some((i) => i.hasOwnProperty(child))) {
    arr.forEach((item) => {
      // 如果最开始没有 pid 表示为第一层
      if (!item.hasOwnProperty("pid")) item.pid = "-1";
      if (item[child] && item[child].length) {
        arr.push(...item[child].map((i) => ({ ...i, pid: item.id })));
      }
      delete item[child];
    });
  }
  return arr;
}

10. 通过 pid 和 id 关联的数组转树结构

/**
 * 通过 pid 和 id 关联的数组转树结构
 * @param {Array} arr 数组
 * @param {String} child 存放子元素的字段,默认为 children
 * @returns {Array}
 */
function arrToTree(arr, child = "children") {
  let tree = JSON.parse(JSON.stringify(arr));
  tree.forEach((item) => {
    // 通过 pid 和 id 关联添加子节点属性
    item[child] = tree.filter((i) => i.pid === item.id);
    // 移除已关联的节点,由于filter是浅拷贝,所以并不会导致数据丢失
    tree = tree.filter((i) => i.pid !== item.id);
  });
  return tree;
}

/**
 * 通过 pid 和 id 关联的数组转树结构2
 * @param {Array} arr 数组
 * @param {String} child 存放子元素的字段,默认为 children
 * @param {String} rootId 根节点id
 * @returns {Array}
 */
function arrToTree2(arr, child = "children", rootId = "-1") {
  let result = JSON.parse(JSON.stringify(arr));
  return result.reduce((pre, cur, i, arr) => {
    cur[child] = arr.filter((item) => item.pid === cur.id);
    if (cur.pid === rootId) {
      pre.push(cur);
    }
    return pre;
  }, []);
}

11. 数组对象数据过滤,两个一维数组如果存在相同id则替换指定字段,如果不同则添加

/**
 * 数组对象数据过滤,两个一维数组如果存在相同id则替换指定字段,如果不同则添加
 * @param {Array} target 数组1
 * @param {Array} source 数组2
 * @returns {Array}
 */
function dateReplace(target, source) {
  let arr1 = JSON.parse(JSON.stringify(target));
  let arr2 = JSON.parse(JSON.stringify(source));
  arr1.forEach((item) => {
    arr2.find((i) => {
      if (item.id === i.id) {
        // 除了id全部替换过去
        for (let k in i) {
          if (k !== "id") {
            item[k] = i[k];
          }
        }
        // 已经替换过的打个标记,合并的时候不要了
        i.replace = true;
      }
    });
  });
  return [...arr1, ...arr2.filter((item) => !item.replace)];
}

12. 进度转百分比

/**
 * 进度转百分比
 * @param {Number} progress  0 ~ 1
 * @param {Number} type      0:0、1 ==> 0%、100%,1:0、1 ==> 未开始、已完成
 * @returns {Number}         0% ~ 100%
 */
const stepsToRatio = (progress, type = 0) => {
  if (progress === null) progress = Number(progress);
  if (typeof progress !== "number") throw new Error("只能识别数字类型");
  if (type === 1) {
    return progress === 0 ? "未开始" : "已完成";
  }

  return Math.floor(progress * 100) + "%";
};

13. 时间对象转天数

/**
 * 时间对象转天数
 * @param {Date} time 时间对象
 * @returns {Number} 天数
 */
const dateToDay = (time) => +new Date(time) / (1000 * 3600 * 24);

14. 天数转时间对象

/**
 * 天数转时间对象
 * @param {Number} day 天数
 * @returns {Date} 时间对象
 */
const dayToDate = (day) => new Date(day * (1000 * 3600 * 24));

15. 计算两个时间戳相差多少天

/**
 * 计算两个时间戳相差多少天
 * @param {Number | Date | String} startTime 开始时间,时间戳 | 时间对象 | 字符串表示的时间格式("2022-1-1 8:00:00")
 * @param {Number | Date | String} endTime 结束时间
 * @returns {Number} 相差天数
 */
const daysInterval = (startTime, endTime) => Math.abs(Math.round((+new Date(endTime) - +new Date(startTime)) / (1000 * 3600 * 24)));

16. 获取当月天数

/**
 * 获取当月天数
 * @returns {Number} 当月天数
 */
function getDays() {
  let date = new Date();
  date.setMonth(date.getMonth() + 1);
  date.setDate(0);
  return date.getDate();
}

17. 随机生成 16 进制颜色

/**
 * 随机生成 16 进制颜色
 * @returns {String} 颜色
 */
function randomHexcolor() {
  return "#" + Math.random().toString("16").substring(2, 8);
}

18. 控制异步并发数

/**
 * 控制异步并发数
 */
class SuperTask {
  // concurrency:并发数量
  constructor(concurrency = 2) {
    this.concurrency = concurrency;
    this.queueCount = 0;
    this.tasks = [];
  }

  // 添加任务与时间
  addTask(cb, time, resCb) {
    this._add(() => this._timeout(time).then(cb), resCb);
  }

  // 三个辅助函数
  _add(task, resCb) {
    this.tasks.push({
      task,
      resCb,
    });
    this._run();
  }
  async _run() {
    while (this.queueCount < this.concurrency && this.tasks.length) {
      let { task, resCb } = this.tasks.shift();
      this.queueCount++;

      let res = await task();

      resCb && resCb(res);

      this.queueCount--;
      this._run();
    }
  }
  _timeout(time) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve();
      }, time);
    });
  }
}
  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值