js常用方法

防抖和节流
//定义:触发事件后在n秒内函数只能执行一次,如果在n秒内又触发了事件,则会重新计算函数执行时间。
//搜索框搜索输入。只需用户最后一次输入完,再发送请求
//手机号、邮箱验证输入检测 onchange oninput事件
//窗口大小Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。
const debounce = (fn, wait, immediate) => {
      let timer = null;
      return function (...args) {
        if (timer) clearTimeout(timer);
        if (immediate && !timer) {
          fn.call(this, args);
        }
        timer = setTimeout(() => {
          fn.call(this, args);
        }, wait);
      };
    };
const betterFn = debounce(() => console.log("fn 防抖执行了"), 1000, true);
document.addEventListener("scroll", betterFn);

//定义:当持续触发事件时,保证隔间时间触发一次事件。
//1. 懒加载、滚动加载、加载更多或监听滚动条位置;
//2. 搜索框,搜索联想功能;
//3. 防止高频点击提交,防止表单重复提交;
function throttle(fn,wait){
    let pre = 0;
    return function(...args){
        let now = Date.now();
        if( now - pre >= wait){
            fn.apply(this,args);
            pre = now;
        }
    }
}
function handle(){
    console.log(Math.random());
}
window.addEventListener("mousemove",throttle(handle,1000));
对象深浅拷贝
//浅拷贝 
1. Object.assign(target,source)
2. es6对象扩展运算符。
//深拷贝    
function deepClone(obj) {
      if (!obj || typeof obj !== "object") return;
      let newObj = Array.isArray(obj) ? [] : {};
      for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
          newObj[key] = typeof obj[key] === "object" ? deepClone(obj[key]) : obj[key];
        }
      }
      return newObj;
}
数组扁平化
function flatten(arr) {
      return arr.reduce((result, item) => {
        return result.concat(Array.isArray(item) ? flatten(item) : item);
      }, []);
}
数组对象转树
const datas = [
      { id: 2, pid: 0, path: '/course', title: '课程管理' },
      { id: 3, pid: 2, path: '/operate', title: '课程操作' },
      { id: 5, pid: 2, path: '/add', title: '增加课程' },
      { id: 6, pid: 0, path: '/student', title: '学生管理' },
      { id: 7, pid: 6, path: '/studentAdd', title: '添加学生' },
      { id: 8, pid: 6, path: '/studentOperate', title: '学生操作' }
]

// 方法一:
function formarRouterTree (data) {
      let parents = data.filter(p => p.pid === 0),
          children = data.filter(c => c.pid !== 0);

      dataToTree(parents, children);

      function dataToTree (parents, children) {
        parents.map((p) => {
          children.map((c, i) => {
            if (c.pid === p.id) {
              let _c = JSON.parse(JSON.stringify(children));
              _c.splice(i, 1);
              dataToTree([c], _c);

              if (p.children) {
                p.children.push(c);
              } else {
                p.children = [c];
              }
            }
          })
        })
      }
      return parents;
}
const routers = formarRouterTree(datas)
console.log(routers)

// 方法二:
const firstNode = datas.filter(v => !v.pid)

function loop(_datas, ret) {
      for (const item of ret) {
        const children = _datas.filter(v => v.pid === item.id)
        item.children = loop(_datas, children);
      }
      return ret;
};
const result = loop(datas, firstNode);
console.log(result, 'result');

// 方法三:
/**
 * 扁平化数组转换成树形数组
 * @param {Array} data  需要转换的数组
 * @param {string} id  id
 * @param {string} pid  父id
 * @return {Array} 树形数组
 */
getTreeData(data, id = "id", pid = "pid") {
    let cloneData = JSON.parse(JSON.stringify(data));
    return cloneData.filter(parent => {
        let branchArr = cloneData.filter(
            child => parent[id] == child[pid]
        );
        for (let i = 0; i < branchArr.length; i++) {
            branchArr.parent_nickname = parent.nickname;
        }
        branchArr.length > 0 ? (parent["children"] = branchArr) : "";
        return parent[pid] === null;
    });
}
根据条件一维数组转二维数组
const arr = [
    { name: '1', type: 1 },
    { name: '2', type: 1 },
    { name: '3', type: 1 },
    { name: '4', type: 2 },
    { name: '5', type: 2 },
    { name: '6', type: 2 },
    { name: '7', type: 2 },
]
// 方法一:
const map1 = arr.reduce((p, c) => [p[c.type] = p[c.type] || [], p[c.type].push(c), p][2], {});
const result = Object.keys(map1).map(i => map1[i])

// 方法二:
const result = Object.values(arr.reduce((res, item) => { 
    res[item.type] ? res[item.type].push(item) : res[item.type] = [item];
    return res;
}, {}));
点击复制内容
function copyFn(event, cpId) {
    var range = document.createRange();
    range.selectNode(document.getElementById(cpId));
    // range.selectNode(document.getElementById('link'));
    var selection = window.getSelection();
    if (selection.rangeCount > 0) selection.removeAllRanges();
    selection.addRange(range);
    document.execCommand('Copy');
    alert('复制成功,快去添加吧')
}
滑轮切换fixed固定底部条
.bar{width:100%;height:70px;background-color:orange;position:relative;text-align:center;line-height:70px;}
.fixed-bar{position:fixed;left:0;bottom:0;}

<div id="adBar"><div class="bar fixed-bar">切换fixed</div></div>

$(window).scroll(function(){
   var position = $('#adBar').position().top; //相对浏览器或者父级的位置    
   var barH = $('.bar').height(); //bar的高度
   var winH = $(window).height(); //窗口的高度
   var winScrollTop = $(window).scrollTop();
   if(winScrollTop >= position - winH + barH){ //计算结果 如果滚动的高度 大于 就正常 否则添加固定在底部的类
       $('.bar').removeClass('fixed-bar');
   }else{
       $('.bar').addClass('fixed-bar');
   }
})


// 页面滑动超过(指定位置)后就让bottomBar一直固定在底部,
// 页面滑动还没超过(指定位置)时就随着页面滚动而滚动
bottomShow();
function bottomShow() {
    var fixedBottom = $('#fixedBottom');
    var bTop = fixedBottom.offset().top - $(window).height() + fixedBottom.height();
    var rTop = $('.reg').offset().top + $('.reg').height();

    $(window).scroll(function () {
        var sTop = $(this).scrollTop();
        if (sTop > rTop) {
            fixedBottom.show();
            if (sTop > bTop) {
                fixedBottom.removeClass('fixed');
            } else {
                fixedBottom.addClass('fixed');
            }
        } else {
            fixedBottom.hide();
        }
    })
} 
判断android & ios or others
const isMobile = {
	Android: function () {
	    return navigator.userAgent.match(/Android/i) ? true : false;
	},
	BlackBerry: function () {
	    return navigator.userAgent.match(/BlackBerry/i) ? true : false;
	},
	iOS: function () {
	    return navigator.userAgent.match(/iPhone|iPad|iPod/i) ? true : false;
	},
	Windows: function () {
	    return navigator.userAgent.match(/IEMobile/i) ? true : false;
	},
	any: function () {
	    return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Windows());
	}
};
if (isMobile.Android()) {
    window.location.href = 'android.htm'
}
获取URL中的参数值
function getQueryString(params) {
    var reg = new RegExp("(^|&)" + params + "=([^&]*)(&|$)", "i");
    var r = window.location.search.substr(1).match(reg);
    if (r != null) return unescape(r[2]); return "";
}
JS将时间转换为 刚刚几秒前几分钟前几小时前几天前、几月前或按照传入格式显示
const formatPast = (date, type = "default", zeroFillFlag = true) => {
        // 定义countTime变量,用于存储计算后的数据
        let countTime;
        // 获取当前时间戳
        let time = new Date().getTime();
        // 转换传入参数为时间戳
        let afferentTime = new Date(date).getTime();
        // 当前时间戳 - 传入时间戳
        time = Number.parseInt(`${time - afferentTime}`);
        if (time < 10000) {
            // 10秒内
            return "刚刚";
        } else if (time < 60000) {
            // 超过10秒少于1分钟内
            countTime = Math.floor(time / 1000);
            return `${countTime}秒前`;
        } else if (time < 3600000) {
            // 超过1分钟少于1小时
            countTime = Math.floor(time / 60000);
            return `${countTime}分钟前`;
        } else if (time < 86400000) {
            // 超过1小时少于24小时
            countTime = Math.floor(time / 3600000);
            return `${countTime}小时前`;
        } else if (time >= 86400000 && type == "default") {
            // 超过二十四小时(一天)且格式参数为默认"default"
            countTime = Math.floor(time / 86400000);
            //大于等于365天
            if (countTime >= 365) {
                return `${Math.floor(countTime / 365)}年前`;
            }
            //大于等于30天
            if (countTime >= 30) {
                return `${Math.floor(countTime / 30)}个月前`;
            }
            return `${countTime}天前`;
        } else {
            // 一天(24小时)以上且格式不为"default"则按传入格式参数显示不同格式
            // 数字补零
            let Y = new Date(date).getFullYear();
            let M = new Date(date).getMonth() + 1;
            let zeroFillM = M > 9 ? M : "0" + M;
            let D = new Date(date).getDate();
            let zeroFillD = D > 9 ? D : "0" + D;
            // 传入格式为"-" "/" "."
            if (type == "-" || type == "/" || type == ".") {
                return zeroFillFlag
                    ? Y + type + zeroFillM + type + zeroFillD
                    : Y + type + M + type + D;
            }
            // 传入格式为"年月日"
            if (type == "年月日") {
                return zeroFillFlag
                    ? Y + type[0] + zeroFillM + type[1] + zeroFillD + type[2]
                    : Y + type[0] + M + type[1] + D + type[2];
            }
            // 传入格式为"月日"
            if (type == "月日") {
                return zeroFillFlag
                    ? zeroFillM + type[0] + zeroFillD + type[1]
                    : M + type[0] + D + type[1]
            }
            // 传入格式为"年"
            if (type == "年") {
                return Y + type
            }

        }
};
console.log(formatPast("2024-1-1 11:11:11")); // 3天前
console.log(formatPast("2023-11-1 11:11:11")); // 2个月前
console.log(formatPast("2015-07-10 21:32:01")); // 8年前
console.log(formatPast("2023-02-01 09:32:01", "-", false)); // 2023-2-1
console.log(formatPast("2023.12.8 19:32:01", "/")); // 2023/12/08
console.log(formatPast("2023.12.8 19:32:01", ".")); // 2023.12.08
console.log(formatPast("2023/5/10 11:32:01", "年月日")); // 2023年05月10日
console.log(formatPast("2023/6/25 11:32:01", "月日", false)); // 6月25日
console.log(formatPast("2023/8/08 11:32:01", "年")); // 2023年

原链接:https://juejin.cn/post/7317704519160266779
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值