阅读 37

javascript-实用的工具类-1

来源:https://juejin.im/post/6875152247714480136

1. 数组扁平化:多维数组-->一维数组

const arr=[1,[2,[3,4]],5] ==> arr = [1,2,3,4,5]

利用reduce

const flatten = arr => {
  return arr.reduce((pre, cur) => {
    return pre.concat(Array.isArray(cur) ? flatten(cur) : cur);
  }, [])
}
const res4 = flatten(arr);
复制代码

2. 数组去重

const arr = [1,1,'1',true,false,true,false,{},{}]

==> arr = [1,'1',true,false,{}]

  • 利用Set const res1 = Array.from(new Set(arr))
  • 利用Map
const unique1 = arr => {
    let map = new Map();
    const res = [];
    for(let i = 0; i < arr.length; i++ ){
        if( !map.has(arr[i]) ) {
            map.set(arr[i], true);
            res.push(arr[i]);
        }
    }
    return res;
}

复制代码

3. 类数组转为数组

ps : 类数组,是具有length属性,但是不具备数组的原型方法。如arguments、DOM操作方法返回结果

let domArr = document.querySelectorAll('div')

  • Array.from ==> Array.from(domArr)
  • 扩展运算符 ==> [... domArr]

4. 防抖(debounce)

触发高频时间后n秒内函数只执行一次,如果n秒内高频时间再次触发,则重新计算时间

    const debounce = (fn ,time) => {
        let timeout = null;

        return function() {
            clearTimeout(timeout);
            timeout = setTimeout( () =>{
                fn.apply(this, arguments);
            } ,time);
        }
    };

复制代码

防抖常应用于用户进行搜索输入节约请求资源,window触发resize事件时进行防抖只触发一次。


5. 节流(throttle)

高频时间触发,但n秒内只执行一次,从而稀释函数的执行频率。常用于鼠标不断点击触发,监听滚动事件


   const throttle = (fn, time) => {
       let flag = true;
       return function() {
           if(!flag) return ;
           flag = flase;
           seTimeout(() => {
               fn.apply(this, agruments);
               flag = true;
           }, time)
       }
   }

复制代码

6. 函数柯里化

多个参数的函数 ==> 一个参数的函数

例子: add(1)(2)(3)(4) = 10

function add() {
 const _args = [...arguments];
 function fn() {
   _args.push(...arguments);
   return fn;
 }
 fn.toString = function() {
   return _args.reduce((sum, cur) => sum + cur);
 }
 return fn;
}

复制代码

7. 图片懒加载


function lazyload() {
 const imgs = document.getElementsByTagName('img');
 const len = imgs.length;
 // 视口的高度
 const viewHeight = document.documentElement.clientHeight;
 // 滚动条高度
 const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop;
 for (let i = 0; i < len; i++) {
   const offsetHeight = imgs[i].offsetTop;
   if (offsetHeight < viewHeight + scrollHeight) {
     const src = imgs[i].dataset.src;
     imgs[i].src = src;
   }
 }
}

// 可以使用节流优化一下
window.addEventListener('scroll', lazyload);

复制代码

8. 滚动加载

 window.addEventListener('scroll', function() {
  const clientHeight = document.documentElement.clientHeight;
  const scrollTop = document.documentElement.scrollTop;
  const scrollHeight = document.documentElement.scrollHeight;
  if (clientHeight + scrollTop >= scrollHeight) {
    // 检测到滚动至页面底部,进行后续操作
    // ...
  }
}, false);

复制代码

9.渲染几万条数据不卡住页面

渲染大数据时,合理使用createDocumentFragment和requestAnimationFrame,将操作切分为一小段一小段执行。

setTimeout(() => {
  // 插入十万条数据
  const total = 100000;
  // 一次插入的数据
  const once = 20;
  // 插入数据需要的次数
  const loopCount = Math.ceil(total / once);
  let countOfRender = 0;
  const ul = document.querySelector('ul');
  // 添加数据的方法
  function add() {
    const fragment = document.createDocumentFragment();
    for(let i = 0; i < once; i++) {
      const li = document.createElement('li');
      li.innerText = Math.floor(Math.random() * total);
      fragment.appendChild(li);
    }
    ul.appendChild(fragment);
    countOfRender += 1;
    loop();
  }
  function loop() {
    if(countOfRender < loopCount) {
      window.requestAnimationFrame(add);
    }
  }
  loop();
}, 0)

复制代码