工具函数封装-杂

66 阅读3分钟

下面封装的一些方式也是比较常用的,但是种类比较多。比较杂,这里就不去对其进行细分,比如有对象的深拷贝、克隆、防抖、节流等等,下面直接将代码放出来即可

// 实现浮点数除法操作
function floatDiv(arg1, arg2) {
  /**
   * t1 t2:用于记录参数 arg1 和 arg2 的小数位数
   */
  var t1 = 0,
    t2 = 0,
    r1,
    r2;

  // 尝试获取 arg1 和 arg2 的小数位数,如果无法获取则忽略异常
  try {
    t1 = arg1.toString().split(".")[1].length;
  } catch (e) {}
  try {
    t2 = arg2.toString().split(".")[1].length;
  } catch (e) {}

  // 将 arg1 和 arg2 的小数点去掉,并转换为数值类型
  r1 = Number(arg1.toString().replace(".", ""));
  r2 = Number(arg2.toString().replace(".", ""));

  // 返回 arg1 / arg2 的结果,并乘以 10 的 (t2 - t1) 次方
  // 得到浮点数除法的结果
  return (r1 / r2) * Math.pow(10, t2 - t1);
}
var stobdata = floatDiv(stob, btos);

/**
 * 用于获取URL中的参数值
 * reg:构造一个含有目标参数的正则表达式对象,用于匹配参数名为_paraName的参数值
 * 例如:/(^|&)type=([^&]*)(&|$)/
 * r:获取当前URL中的参数列表,并匹配参数名为_paraName的参数值
 * substr(1)函数表示去除URL中的问号,match(reg)函数用于执行正则表达式匹配
 * 例如:["type=4", "", "4", ""]
 * if (r != null)...:如果匹配成功,则返回匹配结果中的第二个子字符串(即参数值),
 * 并对其进行URL解码。否则,返回空字符串
 */
GetUrlParam = function (_paraName) {
  var reg = new RegExp("(^|&)" + _paraName + "=([^&]*)(&|$)");
  var r = window.location.search.substr(1).match(reg);
  if (r != null) return decodeURIComponent(r[2]);
  //返回参数值
  return "";
};
var type = GetUrlParam("type");

/**
 * 时间对象的格式化;
 *
 * date:定义了一个变量date,用于存储当前时间
 * var o = {...};:定义了一个包含各种时间属性的对象
 * if (/(y+)/.test(format)) {...}:通过正则表达式匹配字符串format中的年份格式
 * for (var k in o) {...}:遍历对象o,对字符串format中的日期格式进行替换
 */
function format(format) {
  /*
   * eg:format="YYYY-MM-dd hh:mm:ss";
   */
  var date = this;
  var o = {
    "M+": date.getMonth() + 1, //month
    "d+": date.getDate(), //day
    "h+": date.getHours(), //hour
    "m+": date.getMinutes(), //minute
    "s+": date.getSeconds(), //second
    "q+": Math.floor((date.getMonth() + 3) / 3), //quarter
    S: date.getMilliseconds(), //millisecond
  };

  if (/(y+)/.test(format)) {
    format = format.replace(
      RegExp.$1,
      (date.getFullYear() + "").substr(4 - RegExp.$1.length)
    );
  }

  for (var k in o) {
    if (new RegExp("(" + k + ")").test(format)) {
      format = format.replace(
        RegExp.$1,
        RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)
      );
    }
  }
  return format;
}
format("yyyy-MM-dd");

/**
 * 对象深拷贝
 *
 * arguments.callee 在哪一个函数中运行,它就代表哪个函数
 */
function clone(obj) {
  var o, i, j, k;
  //判断如果obj不是对象或为空,则直接返回该值
  if (typeof obj != "object" || obj === null) return obj;
  if (obj instanceof Array) {
    o = [];
    i = 0;
    j = obj.length;
    for (; i < j; i++) {
      //如果obj[i]是对象且不为空
      if (typeof obj[i] == "object" && obj[i] != null) {
        //则递归调用clone函数,并将返回的值赋给o[i]
        o[i] = arguments.callee(obj[i]);
      } else {
        //直接将obj[i]赋给o[i]
        o[i] = obj[i];
      }
    }
  } else {
    o = {};
    //循环obj对象的属性
    for (i in obj) {
      //如果obj[i]是对象且不为空
      if (typeof obj[i] == "object" && obj[i] != null) {
        //则递归调用clone函数,并将返回的值赋给o[i]
        o[i] = arguments.callee(obj[i]);
      } else {
        //直接将obj[i]赋给o[i]
        o[i] = obj[i];
      }
    }
  }

  return o;
}
clone(obj);

/**
 * 将传入的数字格式化为千位分隔符形式的字符串,并保留两位小数
 * @param {*} input
 * @return
 *
 * re:创建一个正则表达式,用于匹配需要添加千位分隔符的数字
 * return...:将数字中需要添加千位分隔符的部分替换为加了逗号的字符串,然后返回格式化后的字符串
 * 
 * var input = 1234567.89;
   var result = formatMoney(input);
   console.log(result); // 输出 "1,234,567.89"
 */
function formatMoney(input) {
  input = input ? input : 0;
  var n = parseFloat(input).toFixed(2);
  var re = /(\d{1,3})(?=(\d{3})+(?:\.))/g;
  return n.replace(re, "$1,");
}

// 数组置顶操作(针对搜索历史,总是把后输入的放在数组最前面)
function __toFirst(arr, index) {
  if (index != 0) {
    arr.unshift(arr.splice(index, 1)[0]);
  }
  return arr;
}

第二波

(function () {
  /**
   * 获取当前浏览器窗口的宽度和高度
   *
   * else if (document.compatMode === "BackCompat"):
   * 如果 window.innerWidth 不存在(即浏览器不支持 innerWidth 属性)
   * 并且文档处于“混杂模式”下,则将文档 body 元素的宽度和高度分别
   * 赋值给 width 和 height 变量
   *
   * else...:如果 window.innerWidth 和 document.compatMode 都不存在,
   * 则将文档的根元素(即 <html> 元素)的宽度和高度
   * 分别赋值给 width 和 height 变量
   *
   * let {x,y} = getScreen();
   * @returns
   */
  function getScreen() {
    let width, height;
    if (window.innerWidth) {
      width = window.innerWidth;
      height = window.innerHeight;
    } else if (document.compatMode === "BackCompat") {
      width = document.body.clientWidth;
      height = document.body.clientHeight;
    } else {
      width = document.documentElement.clientWidth;
      height = document.documentElement.clientHeight;
    }
    return {
      width: width,
      height: height,
    };
  }

  /**
   * 返回当前页面的滚动位置(水平和垂直方向)
   *
   * let {x,y} = getPageScroll();
   * @returns
   */
  function getPageScroll() {
    let x, y;
    if (window.pageXOffset) {
      x = window.pageXOffset;
      y = window.pageYOffset;
    } else if (document.compatMode === "BackCompat") {
      x = document.body.scrollLeft;
      y = document.body.scrollTop;
    } else {
      x = document.documentElement.scrollLeft;
      y = document.documentElement.scrollTop;
    }
    return {
      x: x,
      y: y,
    };
  }

  /**
   * 给DOM元素添加事件监听器的函数
   * @param {*} ele 当前哪个元素
   * @param {*} name 添加事件的名称
   * @param {*} fn 回调函数-事件处理函数
   *
   *let btn = document.querySelector('#myButton');
    function handleClick() {
        alert('Button clicked!');
    }
    addEvent(btn, 'click', handleClick);
   */
  function addEvent(ele, name, fn) {
    // 判断浏览器是否支持 attachEvent 方法
    if (ele.attachEvent) {
      ele.attachEvent("on" + name, fn);
    } else {
      ele.addEventListener(name, fn);
    }
  }

  /**
   * 返回指定 DOM 元素的指定样式属性的值
   * @param {*} obj DOM元素对象
   * @param {*} name 样式属性名
   * @returns
   * 
   * var elem = document.getElementById("myElement");
     var color = getStyleAttr(elem, "color");
   */
  function getStyleAttr(obj, name) {
    if (obj.currentStyle) {
      return obj.currentStyle[name];
    } else {
      return getComputedStyle(obj)[name];
    }
  }

  /**
   * 防抖
   * @param {*} fn 
   * @param {*} delay 
   * @returns 
   * 
   * function handleInput() {
        console.log('Input changed');
    }
    let debouncedHandleInput = debounce(handleInput, 500);
    document.querySelector('input').addEventListener('input', debouncedHandleInput);
   */
  function debounce(fn, delay) {
    let timerId = null;
    return function () {
      let self = this;
      let args = arguments;
      timerId && clearTimeout(timerId);
      timerId = setTimeout(function () {
        fn.apply(self, args);
      }, delay || 1000);
    };
  }

  /**
   * 定义一个需要进行节流的函数
   * @param {*} fn
   * @param {*} delay
   * @returns
   *
    function handleClick() {
        console.log('click');
    }
    // 对 handleClick 函数进行节流,间隔时间为 1000 毫秒
    let throttledHandleClick = throttle(handleClick, 1000);
    // 绑定事件,每次点击会间隔 1000 毫秒才执行 handleClick 函数
    document.addEventListener('click', throttledHandleClick);
   */
  function throttle(fn, delay) {
    let timerId = null;
    let flag = true;
    return function () {
      if (!flag) return;
      flag = false;
      let self = this;
      let args = arguments;
      timerId && clearTimeout(timerId);
      timerId = setTimeout(function () {
        flag = true;
        fn.apply(self, args);
      }, delay || 1000);
    };
  }

  /**
   * 格式化大数字
   * @param {*} num
   * @returns
   *
   * formartNum(50000)会返回"5万"
   */
  function formartNum(num) {
    let res = 0;
    // 判断num是否大于1亿
    if (num / 100000000 > 1) {
      let temp = num / 100000000 + "";
      // 判断字符串temp中是否含有小数点
      if (temp.indexOf(".") === -1) {
        res = num / 100000000 + "亿";
      } else {
        // 如果temp中含有小数点
        res = (num / 100000000).toFixed(1) + "亿";
      }
    }
    // 判断num是否大于1万
    else if (num / 10000 > 1) {
      let temp = num / 10000 + "";
      if (temp.indexOf(".") === -1) {
        res = num / 10000 + "万";
      } else {
        res = (num / 10000).toFixed(1) + "万";
      }
    }
    // num既不大于1亿,也不大于1万
    else {
      res = num;
    }
    return res;
  }

  // 传入毫秒处理成天时分秒
  function formartTime(time) {
    // 2.得到两个时间之间的差值(秒)
    let differSecond = time / 1000;
    // 3.利用相差的总秒数 / 每一天的秒数 = 相差的天数
    let day = Math.floor(differSecond / (60 * 60 * 24));
    day = day >= 10 ? day : "0" + day;
    // 4.利用相差的总秒数 / 小时 % 24;
    let hour = Math.floor((differSecond / (60 * 60)) % 24);
    hour = hour >= 10 ? hour : "0" + hour;
    // 5.利用相差的总秒数 / 分钟 % 60;
    let minute = Math.floor((differSecond / 60) % 60);
    minute = minute >= 10 ? minute : "0" + minute;
    // 6.利用相差的总秒数 % 秒数
    let second = Math.floor(differSecond % 60);
    second = second >= 10 ? second : "0" + second;
    return {
      day: day,
      hour: hour,
      minute: minute,
      second: second,
    };
  }

  /**
   * 格式化日期
   * @param {*} fmt  格式
   * @param {*} date  传入的日期
   * @returns
   * let crtTime = new Date()
   * let res = dateFormart("yyyy-MM-dd hh:mm:ss",crtTime);
   */
  function dateFormart(fmt, date) {
    // 1.处理年
    // 1.1找到yyyy
    // +在正则表达式中表示匹配1个或多个连续的指定字符
    let yearStr = fmt.match(/y+/);
    if (yearStr) {
      yearStr = yearStr[0];
      // 1.2获取到当前的年
      let yearNum = date.getFullYear() + "";
      yearNum = yearNum.substr(4 - yearStr.length);
      // 1.3利用当前的年替换掉yyyy
      fmt = fmt.replace(yearStr, yearNum);
    }
    // 2.处理其他的时间
    let obj = {
      "M+": date.getMonth() + 1,
      "d+": date.getDate(),
      "h+": date.getHours(),
      "m+": date.getMinutes(),
      "s+": date.getSeconds(),
    };
    // 2.1遍历取出所有的时间
    for (let key in obj) {
      // let reg = new RegExp("M+");
      let reg = new RegExp(`${key}`);
      // 取出格式化字符串中对应的格式字符 MM dd hh mm ss
      let fmtStr = fmt.match(reg);
      if (fmtStr) {
        fmtStr = fmtStr[0];
        // 单独处理一位或者两位的时间
        if (fmtStr.length === 1) {
          // 一位
          fmt = fmt.replace(fmtStr, obj[key]);
        } else {
          // 两位
          let numStr = "00" + obj[key];
          numStr = numStr.substr((obj[key] + "").length);
          fmt = fmt.replace(fmtStr, numStr);
        }
      }
    }
    // 3.将格式化之后的字符串返回
    return fmt;
  }

  //对时间戳进行格式化操作
  function formatDate(date) {
    var date = new Date(date);
    var YY = date.getFullYear() + "-";
    var MM =
      date.getMonth() + 1 < 10
        ? "0" + (date.getMonth() + 1) + "-"
        : date.getMonth() + 1 + "-"; // 0 - 11
    var DD =
      date.getDate() < 10
        ? "0" + date.getDate() + "   "
        : date.getDate() + "   "; //1 - 31
    var hh =
      date.getHours() < 10
        ? "0" + date.getHours() + ":"
        : date.getHours() + ":";
    var mm =
      date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
    return YY + MM + DD + hh + mm;
  }

  function getSongs() {
    let songArray = sessionStorage.getItem("history");
    if (!songArray) {
      songArray = [];
    } else {
      songArray = JSON.parse(songArray);
    }
    return songArray;
  }

  function setSong(id, name, singer) {
    let songArray = getSongs();
    let flag = false;
    for (let i = 0; i < songArray.length; i++) {
      let song = songArray[i];
      if (song.id === id) {
        flag = true;
        break;
      }
    }
    if (!flag) {
      songArray.unshift({ id: id, name: name, singer: singer });
      sessionStorage.setItem("history", JSON.stringify(songArray));
    }
  }

  function clearSongs() {
    sessionStorage.removeItem("history");
  }

  function deleteSongByIndex(index) {
    let songArray = getSongs();
    songArray.splice(index, 1);
    sessionStorage.setItem("history", JSON.stringify(songArray));
    return songArray.length;
  }

  //返回指定返回的随机整数
  function getRandomIntInclusive(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值
  }

  window.getScreen = getScreen;
  window.getPageScroll = getPageScroll;
  window.addEvent = addEvent;
  window.getStyleAttr = getStyleAttr;
  window.debounce = debounce;
  window.throttle = throttle;
  window.formartNum = formartNum;
  window.formartTime = formartTime;
  window.dateFormart = dateFormart;
  window.getSongs = getSongs;
  window.setSong = setSong;
  window.clearSongs = clearSongs;
  window.deleteSongByIndex = deleteSongByIndex;
  window.getRandomIntInclusive = getRandomIntInclusive;
  window.formatDate = formatDate;
})();