aromameng / aromameng.github.io

个人博客
https://aromameng.github.io/
0 stars 1 forks source link

【js】基础常用代码 #56

Open aromameng opened 2 years ago

aromameng commented 2 years ago

URLSearchParams 方法

// 创建一个URLSearchParams实例
const urlSearchParams = new URLSearchParams(window.location.search);
// 把键值对列表转换为一个对象
const params = Object.fromEntries(urlSearchParams.entries());

防抖

function debounce(fn, delay) {
  let timer = null
  return function (...args) {
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(() => {
      fn.apply(this, args)
    }, delay)
  }
}

// Demo
function task() {
  console.log('run task')
}
const debounceTask = debounce(task, 1000)
window.addEventListener('scroll', debounceTask)

节流

function throttle(fn, delay) {
  let last = 0 // 上次触发时间
  return (...args) => {
    const now = Date.now()
    if (now - last > delay) {
      last = now
      fn.apply(this, args)
    }
  }
}

// Demo
function task() {
  console.log('run task')
}
const throttleTask = throttle(task, 1000)
window.addEventListener('scroll', throttleTask)
aromameng commented 2 years ago

将数组转树结构

/**
 * 递归查找,获取children
 */
const getChildren = (data, result, pid) => {
  for (const item of data) {
    if (item.pid === pid) {
      const newItem = {...item, children: []};
      result.push(newItem);
      getChildren(data, newItem.children, item.id);
    }
  }
}

/**
* 转换方法
*/
const arrayToTree = (data, pid) => {
  const result = [];
  getChildren(data, result, pid)
  return result;
}
function arrayToTree(items) {
  const result = [];   // 存放结果集
  const itemMap = {};  // 
  for (const item of items) {
    const id = item.id;
    const pid = item.pid;

    if (!itemMap[id]) {
      itemMap[id] = {
        children: [],
      }
    }

    itemMap[id] = {
      ...item,
      children: itemMap[id]['children']
    }

    const treeItem =  itemMap[id];

    if (pid === 0) {
      result.push(treeItem);
    } else {
      if (!itemMap[pid]) {
        itemMap[pid] = {
          children: [],
        }
      }
      itemMap[pid].children.push(treeItem)
    }

  }
  return result;
}
aromameng commented 2 years ago

深拷贝

function deepClone(obj, cache = new WeakMap()) {
  if (typeof obj !== 'object') return obj
  if (obj === null) return obj
  if (cache.get(obj)) return cache.get(obj) // 防止循环引用,程序进入死循环
  if (obj instanceof Date) return new Date(obj)
  if (obj instanceof RegExp) return new RegExp(obj)

  // 找到所属原型上的constructor,所属原型上的constructor指向当前对象的构造函数
  let cloneObj = new obj.constructor()
  cache.set(obj, cloneObj) // 缓存拷贝的对象,用于处理循环引用的情况
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      cloneObj[key] = deepClone(obj[key], cache) // 递归拷贝
    }
  }
  return cloneObj
}

// 测试
const obj = { name: 'Jack', address: { x: 100, y: 200 } }
obj.a = obj // 循环引用
const newObj = deepClone(obj)
console.log(newObj.address === obj.address) // false
aromameng commented 2 years ago

通过 replace 方法获取 url 中的参数键值对,可以快速解析 get 参数。

const q = {};
location.search.replace(/([^?&=]+)=([^&]+)/g,(_,k,v)=>q[k]=v);
console.log(q);
aromameng commented 2 years ago

contenteditable

html 中大部分标签都是不可以编辑的,但是添加了 contenteditable 属性之后,标签会变成可编辑状态。

<div contenteditable="true"></div>
aromameng commented 1 year ago

js 树结构过滤 筛选

filterTree(nodes, query) {
          // 条件就是节点的title过滤关键字
          let predicate = function (node) {
            if (node.compid.includes(query) || node.compname.includes(query)) {
              return true;
            } else {
              return false;
            }
          };

          // 结束递归的条件
          if (!(nodes && nodes.length)) {
            return [];
          }
          let newChildren = [];
          for (let node of nodes) {
            //一、带父节点     以下两个条件任何一个成立,当前节点都应该加入到新子节点集中
            // 1. 子孙节点中存在符合条件的,即 subs 数组中有值
            // 2. 自己本身符合条件
            // let subs = this.filterTree(node.children, query);
            // if (predicate(node)) {
            //   newChildren.push(node);
            // } else if (subs && subs.length) {
            //   node.children = subs;
            //   newChildren.push(node);
            // }

            //二、不带父节点     以下只需要考虑自身的节点满足条件即可,不用带上父节点
            if (predicate(node)) {
              newChildren.push(node);
              node.children = this.filterTree(node.children, query);
            } else {
              newChildren.push(...this.filterTree(node.children, query));
            }
          }
          return newChildren.length ? newChildren : [];
        }
aromameng commented 1 year ago

flat

const deps = {
'数据部':[1,2,3],
'DT部':[5,8,12],
'行政部':[5,14,79],
'人事部':[3,64,105],
}
let member = Object.values(deps).flat(Infinity);
其中使用Infinity作为flat参数,这样可以无需知道被扁平化的数组的维度。
aromameng commented 1 year ago

输入框非空的判断

if((value??'') !== ''){
  //...
}
aromameng commented 1 year ago

页面不可见监听

document.addEventListener('visibilitychange', this.pageVisibleChange);
document.removeEventListener('visibilitychange', this.pageVisibleChange);
pageVisibleChange = () => {
    // 页面变为不可见时触发
    if (document.visibilityState === 'hidden') {

    }
    // 页面变为可见时触发
    if (document.visibilityState === 'visible') {

    }
  };