实用的工具类-1

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

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

利用reduce

  1. const flatten = arr => {
  2. return arr.reduce((pre, cur) => {
  3. return pre.concat(Array.isArray(cur) ? flatten(cur) : cur);
  4. }, [])
  5. }
  6. 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
  1. const unique1 = arr => {
  2. let map = new Map();
  3. const res = [];
  4. for(let i = 0; i < arr.length; i++ ){
  5. if( !map.has(arr[i]) ) {
  6. map.set(arr[i], true);
  7. res.push(arr[i]);
  8. }
  9. }
  10. return res;
  11. }

3. 类数组转为数组

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

let domArr = document.querySelectorAll(‘div’)

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

4. 防抖(debounce)

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

  1. const debounce = (fn ,time) => {
  2. let timeout = null;
  3. return function() {
  4. clearTimeout(timeout);
  5. timeout = setTimeout( () =>{
  6. fn.apply(this, arguments);
  7. } ,time);
  8. }
  9. };

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


5. 节流(throttle)

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

  1. const throttle = (fn, time) => {
  2. let flag = true;
  3. return function() {
  4. if(!flag) return ;
  5. flag = flase;
  6. seTimeout(() => {
  7. fn.apply(this, agruments);
  8. flag = true;
  9. }, time)
  10. }
  11. }

6. 函数柯里化

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

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

  1. function add() {
  2. const _args = [...arguments];
  3. function fn() {
  4. _args.push(...arguments);
  5. return fn;
  6. }
  7. fn.toString = function() {
  8. return _args.reduce((sum, cur) => sum + cur);
  9. }
  10. return fn;
  11. }

7. 图片懒加载

  1. function lazyload() {
  2. const imgs = document.getElementsByTagName('img');
  3. const len = imgs.length;
  4. // 视口的高度
  5. const viewHeight = document.documentElement.clientHeight;
  6. // 滚动条高度
  7. const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop;
  8. for (let i = 0; i < len; i++) {
  9. const offsetHeight = imgs[i].offsetTop;
  10. if (offsetHeight < viewHeight + scrollHeight) {
  11. const src = imgs[i].dataset.src;
  12. imgs[i].src = src;
  13. }
  14. }
  15. }
  16. // 可以使用节流优化一下
  17. window.addEventListener('scroll', lazyload);

8. 滚动加载

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

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

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

  1. setTimeout(() => {
  2. // 插入十万条数据
  3. const total = 100000;
  4. // 一次插入的数据
  5. const once = 20;
  6. // 插入数据需要的次数
  7. const loopCount = Math.ceil(total / once);
  8. let countOfRender = 0;
  9. const ul = document.querySelector('ul');
  10. // 添加数据的方法
  11. function add() {
  12. const fragment = document.createDocumentFragment();
  13. for(let i = 0; i < once; i++) {
  14. const li = document.createElement('li');
  15. li.innerText = Math.floor(Math.random() * total);
  16. fragment.appendChild(li);
  17. }
  18. ul.appendChild(fragment);
  19. countOfRender += 1;
  20. loop();
  21. }
  22. function loop() {
  23. if(countOfRender < loopCount) {
  24. window.requestAnimationFrame(add);
  25. }
  26. }
  27. loop();
  28. }, 0)