JS中实用的工具函数

视频全屏

      // 全屏
      function fullScreen(el) {
        const isFullscreen =
          document.fullScreen ||
          document.mozFullScreen ||
          document.webkitIsFullScreen;
        if (!isFullscreen) {
          //进入全屏,多重短路表达式
          (el.requestFullscreen && el.requestFullscreen()) ||
            (el.mozRequestFullScreen && el.mozRequestFullScreen()) ||
            (el.webkitRequestFullscreen && el.webkitRequestFullscreen()) ||
            (el.msRequestFullscreen && el.msRequestFullscreen());
        } else {
          //退出全屏,三目运算符
          document.exitFullscreen
            ? document.exitFullscreen()
            : document.mozCancelFullScreen
            ? document.mozCancelFullScreen()
            : document.webkitExitFullscreen
            ? document.webkitExitFullscreen()
            : "";
        }
      }

找出数字在数组中下一个相邻的元素

let i = "";
let rr = [];

const name = (n, arr1)=>{
    let num = Number(n);
    for (let i = 0; i < arr1.length; i++) {
        const element = arr1[i];
        if (element != num) {
            rr.push(num--);
        }
    }
    return rr.find((el) => {
        let newel = String(el);
        return arr1.includes(newel);
    })}

let arr = ["2", "4", "6", "8", "10", "12", "14", "16", "18", "20", "22", "24", "27", "30", "33", "36", "42", "48", "54", "60"]
console.log(name('5',arr)); //4

格式化时间

/**
 * @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() +
      '分'
    )
  }
}

解析时间

/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string | null}
 */
function parseTime(time, cFormat) {
  if (arguments.length === 0 || !time) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if ((typeof time === 'string')) {
      if ((/^[0-9]+$/.test(time))) {
        // support "1548221490638"
        time = parseInt(time)
      } else {
        // support safari
        // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
        time = time.replace(new RegExp(/-/gm), '/')
      }
    }

    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(/{([ymdhisa])+}/g, (result, key) => {
    const value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] }
    return value.toString().padStart(2, '0')
  })
  return time_str
}

解析Url地址

/**
 * @param {string} url
 * @returns {Object}
 */
function param2Obj(url) {
  const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
  if (!search) {
    return {}
  }
  const obj = {}
  const searchArr = search.split('&')
  searchArr.forEach(v => {
    const index = v.indexOf('=')
    if (index !== -1) {
      const name = v.substring(0, index)
      const val = v.substring(index + 1, v.length)
      obj[name] = val
    }
  })
  return obj
}

合并两个对象

/**
 * Merges two objects, giving the last one precedence
 * @param {Object} target
 * @param {(Object|Array)} source
 * @returns {Object}
 */
function objectMerge(target, source) {
  if (typeof target !== 'object') {
    target = {}
  }
  if (Array.isArray(source)) {
    return source.slice()
  }
  Object.keys(source).forEach(property => {
    const sourceProperty = source[property]
    if (typeof sourceProperty === 'object') {
      target[property] = objectMerge(target[property], sourceProperty)
    } else {
      target[property] = sourceProperty
    }
  })
  return target
}

数组去重

/**
 * @param {Array} arr
 * @returns {Array}
 */
function uniqueArr(arr) {
  return Array.from(new Set(arr))
}

防抖

在一定时间间隔内,多次调用一个方法,只会执行一次.

/**
 * @param {Function} func
 * @param {number} wait
 * @param {boolean} immediate
 * @return {*}
 */
function debounce(func, wait, immediate) {
  let timeout, args, context, timestamp, result

  const later = function() {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp

    // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last)
    } else {
      timeout = null
      // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args)
        if (!timeout) context = args = null
      }
    }
  }

  return function(...args) {
    context = this
    timestamp = +new Date()
    const callNow = immediate && !timeout
    // 如果延时不存在,重新设定延时
    if (!timeout) timeout = setTimeout(later, wait)
    if (callNow) {
      result = func.apply(context, args)
      context = args = null
    }

    return result
  }
}
/**
 * 防抖
 * @param {Function} func 要执行的回调函数
 * @param {Number} wait 延时的时间
 * @param {Boolean} immediate 是否立即执行
 * @return null
 */
let timeout;
export default function Debounce(func, wait = 3000, immediate = true) {
  // 清除定时器
  if (timeout !== null) clearTimeout(timeout);
  // 立即执行,此类情况一般用不到
  if (immediate) {
    var callNow = !timeout;
    timeout = setTimeout(function() {
      timeout = null;
    }, wait);
    if (callNow) typeof func === 'function' && func();
  } else {
    // 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法
    timeout = setTimeout(function() {
      typeof func === 'function' && func();
    }, wait);
  }
}

//使用
Debounce(()=>{
	console.log(1);
});


节流

多次调用方法,按照一定的时间间隔执行

// ①定时器实现
const throttle = (fn,delay = 500) =>{
  let flag = true;
  return (...args) => {
    if(!flag) return;
    flag = false;
    setTimeout(() => {
      fn.apply(this,args);
      flag = true;
    },delay);
  };
}
// ②时间戳实现
const throttle = (fn,delay = 500) => {
  let preTime = Date.now();
  return (...args) => {
    const nowTime = Date.now();
    if(nowTime - preTime >= delay){
      	preTime = Date.now();
      	fn.apply(this,args);
    }
  }
}

简易搜索

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <input type="text" id="int">
</body>
<script>
  let list = ["示例1","示例12","示例5","示例56"];
  document.querySelector('#int').onchange=function(e){
    console.log(search(e.target.value));
  }
  
  function search(val) {
    if (val) {
        return list.filter(function (item) {
          return Object.keys(item).some(function (key) {
            return String(item[key]).toLowerCase().indexOf(val) > -1
          })
        })
    }
    return list 
  }

</script>
</html>

将秒化为时分秒

function formateSeconds (endTime) {
      let secondTime = parseInt(endTime); //将传入的秒的值转化为Number
      let min = 0; // 初始化分
      let h = 0; // 初始化小时
      let result = "";
      if (secondTime > 60) {
        //如果秒数大于60,将秒数转换成整数
        min = parseInt(secondTime / 60); //获取分钟,除以60取整数,得到整数分钟
        secondTime = parseInt(secondTime % 60); //获取秒数,秒数取佘,得到整数秒数
        if (min > 60) {
          //如果分钟大于60,将分钟转换成小时
          h = parseInt(min / 60); //获取小时,获取分钟除以60,得到整数小时
          min = parseInt(min % 60); //获取小时后取佘的分,获取分钟除以60取佘的分
        }
      }
      result = `${h.toString().padStart(2, "0")}:${min.toString().padStart(2, "0")}:${secondTime.toString().padStart(2, "0")}`;
      return result;
    }
    

将时分秒化为秒

function formSeconds (times) {
        let arr = times.split(":");
        let s = arr[2];
        let m = arr[1];
        let h = arr[0];
        let m1 = m<10?m.replace(/\b(0+)/gi,""):m;
        let h1 = h<10?h.replace(/\b(0+)/gi,""):h;
        return m1*60+Number(h1)+Number(s)
}

对象深层遍历

var obj = {
		a:{
			b:{
				c:"maomin"
			}
		}
	}
const safeGet = (obj, path) => {
        try {
          return path.split('.').reduce((o, k) => o[k], obj)
        } catch (e) {
          return undefined
        }
    }
console.log(safeGet(obj,'a.b.c'));// maomin

带有分割符的字符串转化成一个n维数组

 var str = "A-2-12";
 var str1 = str.split('-');
 var arr = str1.reverse().reduce((pre,cur,i) => {
 if(i==0)
  { pre.push(cur)
   return pre
 }
  return [cur,pre]
},[])
console.log(arr) // ["A"["B",["C"]]]

获取时间戳

  function thedata(d){
      return d.replace(/\-/g, "\/")
  }
  var serverTime = parseInt(new Date(thedata('2020-08-12 15:52:11')).valueOf());
  console.log(serverTime); // 1597218731000,获取到时间戳

对象深拷贝

function deepClone(target) {
    // 定义一个变量
    let result;
    // 如果当前需要深拷贝的是一个对象的话
    if (typeof target === 'object') {
    // 如果是一个数组的话
        if (Array.isArray(target)) {
            result = []; // 将result赋值为一个数组,并且执行遍历
            for (let i in target) {
                // 递归克隆数组中的每一项
                result.push(deepClone(target[i]))
            }
         // 判断如果当前的值是null的话;直接赋值为null
        } else if(target===null) {
            result = null;
         // 判断如果当前的值是一个RegExp对象的话,直接赋值    
        } else if(target.constructor===RegExp){
            result = target;
        }else {
         // 否则是普通对象,直接for in循环,递归赋值对象的所有值
            result = {};
            for (let i in target) {
                result[i] = deepClone(target[i]);
            }
        }
     // 如果不是对象的话,就是基本数据类型,那么直接赋值
    } else {
        result = target;
    }
     // 返回最终结果
    return result;
}

简易版对象拷贝

 function copy(obj) {
    if(typeof obj == "object") { //判断是否复杂类型
       var result = obj.constructor == Array ? [] : {};//判断数组类型或是object,数组即result=[],object即result={}
        for(let i in obj) {
            result[i] = typeof obj[i] == "object" ? copy(obj[i]) : obj[i]//判断数据每一项是否是object
        }
    } else {
        var result = obj //基本类型直接拷贝
    }
  return result;
}

实现一个模板引擎

function render(template, data) {
  const reg = /\{\{(\w+)\}\}/; // 模板字符串正则
  if (reg.test(template)) { // 判断模板里是否有模板字符串
    const name = reg.exec(template)[1]; // 查找当前模板里第一个模板字符串的字段
    template = template.replace(reg, data[name]); // 将第一个模板字符串渲染
    return render(template, data); // 递归的渲染并返回渲染后的结构
  }
  return template; // 如果模板没有模板字符串直接返回
}
let template = '我是{{name}},年龄{{age}},性别{{sex}}';
let data = {
  name: '姓名',
  age: 18
}
render(template, data); // 我是姓名,年龄18,性别undefined

封装fetch

/**
 * 封装fetch函数,用Promise做回调
 * @type {{get: (function(*=)), post: (function(*=, *=))}}
 */
const fetchUtil = {
    get: (url) => {
        return new Promise((resolve, reject) => {
            fetch(url, {
                method: 'GET',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                }
            }).then((response) => response.json()).then(response => {
                resolve(response);
            }).catch(err => {
                reject(new Error(err));
            });
        });
    },
    post: (url, params) => {
        return new Promise((resolve, reject) => {
            fetch(url, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: params
            }).then((response) => response.json()).then(response => {
                resolve(response);
            }).catch(err => {
                reject(new Error(err));
            });
        });
    }
};

判断浏览器环境

function getSystem(){
    const mac = /mac/i,
        linux = /linux/i,
        win = /win/i;
    const platform = navigator.platform.toLowerCase();
    if(mac.test(platform)){
        return 'MAC';
    } else if(win.test(platform)){
        return 'WIN';
    } else if(linux.test(platform)){
        return 'Linux';
    }
    return undefined;
}
const browser = { 
    versions:function(){ 
        let ret = 'xxSys';
        const u = navigator.userAgent;
        const isMobile = !!u.match(/AppleWebKit.*Mobile.*/),
            ios = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/),
            android = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1;
        if(isMobile){
            if(ios) return 'IOS';
            if(android) return 'Android';
        } else {
            ret = getSystem() || ret;
        }
        return ret;
    }(),
};

定义数组内部对象形式

const objArrtransArr = (olddata, oldval, oldname)=>{
    const newArr = [];
    olddata.forEach(item => {
        // 定义数组内部对象形式
        let obj = {};
        obj.value = item[oldval];
        obj.name = item[oldname];
        // 将对象数据推到数组中
        newArr.push(obj);
    });
    return newArr;
}

解析html字符串

function (htmlobj) {
	      var el = document.createElement('div');
	      el.innerHTML = htmlobj;
	      var tags = el.getElementsByTagName('img');
	      var text = tags[0].getAttribute("src");
	      return text;
}

判断浏览器是否支持摄像头

function videoCheck () {
      var deviceList = [];
      navigator.mediaDevices
        .enumerateDevices()
        .then(devices => {
          devices.forEach(device => {
            deviceList.push(device.kind);
          });
          if (deviceList.indexOf("videoinput") == "-1") {
            console.info("没有摄像头");
            return false;
          } else {
            console.info("有摄像头");
          }
        })
        .catch(function(err) {
          alert(err.name + ": " + err.message);
        });
    }

回文算法

  //忽略标点符号、大小写和空格,正着读和反着读一模一样。
function made(str) {
        var str1 = str.toLowerCase(); //先将字符串全部转换为小写
        var reg = /[\W\_]/g; // 删除所有非字母数字字符和下划线
        var str2 = str1.replace(reg, ""); // 去掉非字母和非数字
        var str3 = str2.split(""); // 字符串分隔成数组
        var str4 = str3.reverse(); // 反转数组中的元素
        var str5 = str4.join(""); // 反转后的数组转化为字符串
        return str2 === str5;
}

函数只执行一次

function once (fn){
  let called = false
  return function () {
    if (!called) {
      called = true
      fn.apply(this, arguments)
    }
  }
}
function func (){
    console.log(1);
}

//调用闭包函数
let onlyOnce = once(func);

onlyOnce(); // 1
onlyOnce();

构造函数回调方法

        function Watcher(cb){
            this.cb = cb;
        }
        Watcher.prototype.get=function(data){
            this.cb(data);
        }
        new Watcher((v)=>{
            console.log(v);
        }).get('admin');

用 apply 将数组各项添加到另一个数组

var array = ['a', 'b'];
var elements = [0, 1, 2];
array.push.apply(array, elements);
console.info(array); // ["a", "b", 0, 1, 2]

微信JS-SDK 调用

import wx from 'weixin-js-sdk' //引入微信js-sdk
import { getWXSignature } from '../request/api'
const custom = function(url, jsApiList) {
  return getWXConfig(url, jsApiList)
}
function getWXConfig(url, jsApiList) {
  getWXSignature({ url })
    .then(res => {
      let { appId, timestamp, noncestr, signature } = res.data
      console.log(appId, timestamp, noncestr, signature, jsApiList, url)
      wx.config({
        debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: appId, // 必填,公众号的唯一标识
        timestamp: timestamp, // 必填,生成签名的时间戳
        nonceStr: noncestr, // 必填,生成签名的随机串
        signature: signature, // 必填,签名
        jsApiList: jsApiList, // 必填,需要使用的JS接口列表
      })
      wx.error(function(res) {
        console.log('wxerr', res)
      })
    })
    .catch(err => {
      console.log(err)
    })
}
export default custom

// ***
getWeiXinConfig() {
      let url = window.location.href
      // let url = encodeURIComponent(location.href.split('#')[0])
      this.$getWXConfig(url, ['scanQRCode'])
}
//微信扫一扫
wxSweep() {
      wx.scanQRCode({
        needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
        scanType: ['barCode'], //'qrCode', 可以指定扫二维码还是一维码,默认二者都有
        success: function(res) {
          var result = res.resultStr // 当needResult 为 1 时,扫码返回的结果
          console.log(result)
          if (this.type === 1) {
            //位置上传
            this.$router.push({
              path: '/updateLocation',
              query: {
                projectId: this.projectId,
                type: 1,
                mac: result,
              },
            })
          } else if (this.type === 2) {
            //模块更换
            this.$router.push({
              path: '/changeModule',
              query: {
                projectId: this.projectId,
                type: 1,
                mac: result,
              },
            })
          } else {
            //开关更换
            this.$router.push({
              path: '/changeSwitch',
              query: {
                projectId: this.projectId,
                type: 1,
                mac: result,
              },
            })
          }
        },
      })
    },

js 递归数组降维

let children = [1, [2, 3], [4, [5, 6, [7, 8]]], [9, 10]];
function simpleNormalizeChildren(children) {
            for (let i = 0; i < children.length; i++) {
                if (Array.isArray(children[i])) {
                    children = Array.prototype.concat.apply([], children);
                    simpleNormalizeChildren(children)
                }
            }
            return children;
        }
console.log(simpleNormalizeChildren(children));
simpleNormalizeChildren(children); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

js 数组降维(二维降一维)

function simpleNormalizeChildren(children) {
            for (let i = 0; i < children.length; i++) {
                if (Array.isArray(children[i])) {
                    return Array.prototype.concat.apply([], children)
                }
            }
            return children
        }
let arrs = [
            [
                '1'
            ],
            [
                '3'
            ]
        ];
 const arr = simpleNormalizeChildren(arrs);
 console.log(arr); // ['1','3']

File对象 转 base64

    inputImage(e) {
      let img = e.target.files[0];
      if (img) {
        this.blobToDataURL(img);
      }
    },
    blobToDataURL(blob) {
      let reader = new FileReader();
      reader.readAsDataURL(blob);
      reader.onload = function(evt) {
        let base64 = evt.target.result;
        console.log(base64);
      };
    },

Vue3

    const oDiv = document.createElement('div');
    const oScript = document.createElement('script');
    oDiv.setAttribute('id', 'app');
    oScript.type = 'text/javascript';
    oScript.src = "https://unpkg.com/vue@next";
    document.body.appendChild(oDiv);
    document.body.appendChild(oScript);


    window.onload = function () {
      const { createApp,ref } = Vue;
      const App = {
        template: `
            <div>{{msg}}</div>
            <p>{{count}}</p>
            `,
        data(){
              return {
                msg:'maomin'
              }
        },
        setup(){
          let count = ref(0);

          return {
            count
          }
        }
    }
     createApp(App).mount('#app');
    }

递归寻找操作(已删除指定项为例)

    // 递归寻找
    recursion(data, id) {
      let result;
      if (!data) {
        return;
      }
      for (let i = 0; i < data.length; i++) {
        let item = data[i];
        if (item.breakerId === id) {
          result = item;
          data.splice(i, 1);
          break;
        } else if (item.childrenBranch && item.childrenBranch.length > 0) {
          result = this.recursion(item.childrenBranch, id);
          if (result) {
            return result;
          }
        }
      }

      return result;
    },

递归数组,将数组为空设为undefined

   function useTree(data) {
        for (let index = 0; index < data.length; index++) {
          const element = data[index];
          if (element.childrenBranch.length < 1) {
            element.childrenBranch = undefined;
          } else {
            useTree(element.childrenBranch);
          }
        }
        return data;
      }

数组对象中相同属性值的个数

  group(arr) {
      var obj = {};
      if (Array.isArray(arr)) {
        for (var i = 0; i < arr.length; ++i) {
          var isNew = arr[i].isNew;
          if (isNew in obj) obj[isNew].push(arr[i]);
          else obj[isNew] = [arr[i]];
        }
      }
      return obj;
    },
    max(obj) {
      var ret = 0;
      if (obj && typeof obj === "object") {
        for (var key in obj) {
          var length = obj[key].length;
          if (length > ret) ret = length;
        }
      }
      return ret;
    },
var data = [
	{
	 addr: "1",
	 isNew: false,
	},
	{
	 addr: "2",
	 isNew: false,
	}
]
max(group(data) // 2

检测版本是vue3

import { h } from 'vue';
const isVue3 = typeof h === 'function';
console.log(isVue3)

检测数据对象中是否有空对象

let arr = [{},{name:'1'}]
const arr = this.bannerList.filter(item =>
       item == null || item == '' || JSON.stringify(item) == '{}'
);
 console.log(arr.length > 0 ? '不通过' : '通过')

深拷贝

 /* @param {*} obj
 * @param {Array<Object>} cache
 * @return {*}
 */
function deepCopy (obj, cache = []) {
  // just return if obj is immutable value
  if (obj === null || typeof obj !== 'object') {
    return obj
  }

  // if obj is hit, it is in circular structure
  const hit = find(cache, c => c.original === obj)
  if (hit) {
    return hit.copy
  }

  const copy = Array.isArray(obj) ? [] : {}
  // put the copy into cache at first
  // because we want to refer it in recursive deepCopy
  cache.push({
    original: obj,
    copy
  })

  Object.keys(obj).forEach(key => {
    copy[key] = deepCopy(obj[key], cache)
  })

  return copy
}

const objs = {
	name:'maomin',
	age:'17'
}

console.log(deepCopy(objs));

h5文字转语音

speech(txt){
	var synth = null;
	var msg = null;
	synth = window.speechSynthesis;
	msg = new SpeechSynthesisUtterance();
	msg.text = txt;
	msg.lang = "zh-CN";
	synth.speak(msg);
	if(window.speechSynthesis.speaking){
	  console.log("音效有效");
	 } else {
	 console.log("音效失效");
	 }
 }

模糊搜索

       recursion(data, name) {
            let result;
            if (!data) {
                return;
            }
            for (var i = 0; i < data.length; i++) {
                let item = data[i];
                if (item.name.toLowerCase().indexOf(name) > -1) {
                    result = item;
                    break;
                } else if (item.children && item.children.length > 0) {
                    result = this.recursion(item.children, name);
                    if (result) {
                        return result;
                    }
                }
            }
            return result;
        },
        onSearch(v) {
            if (v) {
                if (!this.recursion(this.subtable, v)) {
                    this.$message({
                        type: 'error',
                        message: '搜索不到',
                    });
                } else {
                    this.tableData = [this.recursion(this.subtable, v)];
                }
            }
        },

input 数字类型

       <el-input
                        v-model.number="form.redVal"
                        type="number"
                        @keydown.native="channelInputLimit"
                        placeholder="请输入阈值设定"
                        maxlength="8"
     ></el-input>

        channelInputLimit(e) {
            let key = e.key;
            // 不允许输入‘e‘和‘.‘
            if (key === 'e' || key === '.') {
                e.returnValue = false;
                return false;
            }
            return true;
        },

排序(交换位置)

    const list = [1,2,3,4,5,6];
    function useChangeSort (arr,oldIndex,newIndex){
    	const targetRow = arr.splice(oldIndex, 1)[0];
    	const targetRow1 = arr.splice(newIndex, 1)[0];
        arr.splice(newIndex, 0, targetRow);
        arr.splice(oldIndex, 0, targetRow1);
        return arr
    }
    console.log(useChangeSort(list,5,0)); // [6, 2, 3, 4, 5, 1]

格式化时间

/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string | null}
 */
export function parseTime(time, cFormat) {
    if (arguments.length === 0 || !time) {
        return null;
    }
    const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}';
    let date;
    if (typeof time === 'object') {
        date = time;
    } else {
        if (typeof time === 'string') {
            if (/^[0-9]+$/.test(time)) {
                // support "1548221490638"
                time = parseInt(time);
            } else {
                // support safari
                // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
                time = time.replace(new RegExp(/-/gm), '/');
            }
        }

        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(/{([ymdhisa])+}/g, (result, key) => {
        const value = formatObj[key];
        // Note: getDay() returns 0 on Sunday
        if (key === 'a') {
            return ['日', '一', '二', '三', '四', '五', '六'][value];
        }
        return value.toString().padStart(2, '0');
    });
    return time_str;
}

将对象的值收集到数组中

const info = { name: "Matt", country: "Finland", age: 35 };


// LONGER FORM
let data = [];
for (let key in info) {
  data.push(info[key]);
}


// SHORTHAND
const data = Object.values(info);

检查一个项目是否存在于数组中

let numbers = [1, 2, 3];


// LONGER FORM
const hasNumber1 = numbers.indexOf(1) > -1 // -> True


// SHORTHAND/CLEANER APPROACH
const hasNumber1 = numbers.includes(1)     // -> True

压缩多个条件

const num = 1;


// LONGER FORM
if(num == 1 || num == 2 || num == 3){
  console.log("Yay");
}


// SHORTHAND
if([1,2,3].includes(num)){
  console.log("Yay");
}

指数运算符

// LONGER FORM
Math.pow(4,2); // 16
Math.pow(2,3); // 8


// SHORTHAND
4**2 // 16
2**3 // 8

Math.floor() 简写

// LONG FORM
Math.floor(5.25) // -> 5.0


// SHORTHAND
~~5.25 // -> 5.0

用一行代码分配多个值

let num1, num2;


// LONGER FORM
num1 = 10;
num2 = 100;


// SHORTHAND
[num1, num2] = [10, 100];

从数组中查找特定元素

const fruits = [
  { type: "Banana", color: "Yellow" },
  { type: "Apple", color: "Green" }
];


// LONGER FORM
let yellowFruit;
for (let i = 0; i < fruits.length; ++i) {
  if (fruits[i].color === "Yellow") {
    yellowFruit = fruits[i];
  }
}


// SHORTHAND
yellowFruit = fruits.find((fruit) => fruit.color === "Yellow");

类固醇的字符串

const age = 41;
const sentence = `I'm ${age} years old`;
let num1 = 20;
let num2 = 10;
console.log(`Sum = ${num1 + num2} and Subtract = ${num1 - num2}`);
//=> Sum = 30 and Subtract = 10
// result: I'm 41 years old

获取文件后缀名

/**
 * 获取文件后缀名
 * @param {String} filename
 */
 export function getExt(filename) {
    if (typeof filename == 'string') {
        return filename
            .split('.')
            .pop()
            .toLowerCase()
    } else {
        throw new Error('filename must be a string type')
    }
}
//使用方式
getExt("1.mp4") //->mp4

复制内容到剪贴板

export function copyToBoard(value) {
    const element = document.createElement('textarea')
    document.body.appendChild(element)
    element.value = value
    element.select()
    if (document.execCommand('copy')) {
        document.execCommand('copy')
        document.body.removeChild(element)
        return true
    }
    document.body.removeChild(element)
    return false
}

//如果复制成功返回true
copyToBoard('lalallala')

休眠多少毫秒

/**
 * 休眠xxxms
 * @param {Number} milliseconds
 */
export function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms))
}

//使用方式
const fetchData=async()=>{
 await sleep(1000)
}

生成随机字符串

/**
 * 生成随机id
 * @param {*} length
 * @param {*} chars
 */
export function uuid(length, chars) {
    chars =
        chars ||
        '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    length = length || 8
    var result = ''
    for (var i = length; i > 0; --i)
        result += chars[Math.floor(Math.random() * chars.length)]
    return result
}

//第一个参数指定位数,第二个字符串指定字符,都是可选参数,如果都不传,默认生成8位
uuid() 

简单的深拷贝

/**
 *深拷贝
 * @export
 * @param {*} obj
 * @returns
 */
export function deepCopy(obj) {
    if (typeof obj != 'object') {
        return obj
    }
    if (obj == null) {
        return obj
    }
    return JSON.parse(JSON.stringify(obj))
}

const person={name:'xiaoming',child:{name:'Jack'}}
deepCopy(person) //new person

数组去重

/**
 * 数组去重
 * @param {*} arr
 */
export function uniqueArray(arr) {
    if (!Array.isArray(arr)) {
        throw new Error('The first parameter must be an array')
    }
    if (arr.length == 1) {
        return arr
    }
    return [...new Set(arr)]
}

uniqueArray([1,1,1,1,1])//[1]

对象转化为FormData对象

/**
 * 对象转化为formdata
 * @param {Object} object
 */

 export function getFormData(object) {
    const formData = new FormData()
    Object.keys(object).forEach(key => {
        const value = object[key]
        if (Array.isArray(value)) {
            value.forEach((subValue, i) =>
                formData.append(key + `[${i}]`, subValue)
            )
        } else {
            formData.append(key, object[key])
        }
    })
    return formData
}

let req={
    file:xxx,
    userId:1,
    phone:'15198763636',
    //...
}
fetch(getFormData(req))

保留到小数点以后n位

// 保留小数点以后几位,默认2位
export function cutNumber(number, no = 2) {
    if (typeof number != 'number') {
        number = Number(number)
    }
    return Number(number.toFixed(no))
}

后台管理中常用的工具类函数

校验数据类型

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

示例:

typeOf('树哥')  // string
typeOf([])  // array
typeOf(new Date())  // date
typeOf(null) // null
typeOf(true) // boolean
typeOf(() => { }) // function

防抖

export const debounce = (() => {
  let timer = null
  return (callback, wait = 800) => {
    timer&&clearTimeout(timer)
    timer = setTimeout(callback, wait)
  }
})()
示例:
如 vue 中使用

methods: {
  loadList() {
    debounce(() => {
      console.log('加载数据')
    }, 500)
  }
}

节流

export const throttle = (() => {
  let last = 0
  return (callback, wait = 800) => {
    let now = +new Date()
    if (now - last > wait) {
      callback()
      last = now
    }
  }
})()

手机号脱敏

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

开启全屏

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()
  }
}

关闭全屏

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()
  }
}

大小写转换

//参数:

//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
  }
}

//示例:

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

解析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
}
//示例:

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

判断手机是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;
}

数组对象根据字段去重

//参数:

//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
}

//示例:

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: '张麻子' }]

滚动到页面顶部

export const scrollToTop = () => {
  const height = document.documentElement.scrollTop || document.body.scrollTop;
  if (height > 0) {
    window.requestAnimationFrame(scrollToTop);
    window.scrollTo(0, height - height / 8);
  }
}

滚动到元素位置

export const smoothScroll = element =>{
    document.querySelector(element).scrollIntoView({
        behavior: 'smooth'
    });
};

//示例:

smoothScroll('#target'); // 平滑滚动到 ID 为 target 的元素

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

金额格式化

//参数:

//{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

存储操作

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()

模糊搜索

//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: '树哥'}]

遍历树节点

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
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值