列表转树
const buildTreeList = (list: any[]) => {
let temp: any = {};
let tree: any = [];
list.forEach((item: any) => {
temp[item.key] = item;
})
for(let i in temp){
if(temp[i].parentId) {
if(!temp[temp[i].parentId].children) {
temp[temp[i].parentId].children = [];
}
temp[temp[i].parentId].children= [...temp[temp[i].parentId].children,temp[i]]
} else {
tree.push(temp[i])
}
}
return {tree, temp};
}
类型判断工具函数
function type(data) {
return Object.prototype.toString.call(data)
.slice(8,-1)
.toLowerCase()
}
防抖
function debounce(fn, delay = 500) {
let timer = null
return function () {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(this, arguments)
timer = null
}, delay)
}
}
input1.addEventListener('keyup', debounce(function (e) {
console.log(e.target)
console.log(input1.value)
}, 600))
节流
function throttle(fn, delay = 100) {
let timer = null
return function () {
if (timer) {
return
}
timer = setTimeout(() => {
fn.apply(this, arguments)
timer = null
}, delay)
}
}
div1.addEventListener('drag', throttle(function (e) {
console.log(e.offsetX, e.offsetY)
}))
div1.addEventListener('drag', function(event) {
})
空对象判断
空对象判断
function isEmptyObject(obj) {
return !!obj ? (Object.getOwnPropertyNames(obj).length === 0) : true;
return JSON.stringify(obj) === '{}'
}
浏览器关闭时清空localStorage储存的数据
function setCookie(name, value, seconds) {
seconds = seconds || 0;
var expires = "";
if (seconds != 0) {
var date = new Date();
date.setTime(date.getTime() + (seconds * 1000));
expires = "; expires=" + date.toGMTString();
}
document.cookie = name + "=" + escape(value) + expires + "; path=/";
}
function setInof(key, value) {
localStorage.setItem(key, value);
setCookie(key,value)
}
function getCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1, c.length);
}
if (c.indexOf(nameEQ) == 0) {
return unescape(c.substring(nameEQ.length, c.length));
}
}
return false;
}
if(!getCookie('Token')){
localStorage.clear();
}
手写深拷贝
function deepClone(obj = {}) {
if (typeof obj !== 'object' || obj == null) {
return obj
}
let result
if (obj instanceof Array) {
result = []
} else {
result = {}
}
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
result[key] = deepClone(obj[key])
}
}
return result
}
bind函数
Function.prototype.bind1 = function () {
const args = Array.prototype.slice.call(arguments)
const t = args.shift()
const self = this
return function () {
return self.apply(t, args)
}
}
function fn1(a, b, c) {
console.log('this', this)
console.log(a, b, c)
return 'this is fn1'
}
const fn2 = fn1.bind1({x: 100}, 10, 20, 30)
const res = fn2()
console.log(res)
clearfix
.clearfix:after {
content: '';
display: table;
clear: both;
}
.clearfix{
*zoom: 1;
}
深度比较,模拟lodash.isEqual
function isObject(obj) {
return typeof obj === 'object' && obj !== null
}
function isEqual(obj1, obj2) {
if (!isObject(obj1) || !isObject(obj2)) {
return obj1 === obj2
}
if (obj1 === obj2) {
return true
}
const obj1Keys = Object.keys(obj1)
const obj2Keys = Object.keys(obj2)
if (obj1Keys.length !== obj2Keys.length) {
return false
}
for (let key in obj1) {
const res = isEqual(obj1[key], obj2[key])
if (!res) {
return false
}
}
return true
}
const obj1 = {
a: 100,
b: {
x: 100,
y: 200
}
}
const obj2 = {
a: 100,
b: {
x: 100,
y: 200
}
}
console.log( isEqual(obj1, obj2) )
const arr1 = [1, 2, 3]
const arr2 = [1, 2, 3, 4]
数组 flaten,考虑多层级
function flat(arr) {
const isDeep = arr.some(item => item instanceof Array)
if (!isDeep) {
return arr
}
const res = Array.prototype.concat.apply([], arr)
return flat(res)
}
const res = flat( [1, 2, [3, 4, [10, 20, [100, 200]]], 5] )
console.log(res)
字符串trim方法,保证浏览器兼容性
String.prototype.trim = function() {
return this.replace(/^\s+/,'').replace(/\s+$/,'')
}
简易jQuery考虑插件和扩展性代码演示
class jQuery {
constructor(selector) {
const result = document.querySelectorAll(selector)
const length = result.length
for (let i = 0; i < length; i++) {
this[i] = result[i]
}
this.length = length
this.selector = selector
}
get(index) {
return this[index]
}
each(fn) {
for (let i = 0; i < this.length; i++) {
const elem = this[i]
fn(elem)
}
}
on(type, fn) {
return this.each(elem => {
elem.addEventListener(type, fn, false)
})
}
}
jQuery.prototype.dialog = function (info) {
alert(info)
}
class myJQuery extends jQuery {
constructor(selector) {
super(selector)
}
addClass(className) {
}
style(data) {
}
}
一个简易的ajax
function ajax(url) {
const p = new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open('GET', url, true)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
resolve(
JSON.parse(xhr.responseText)
)
} else if (xhr.status === 404 || xhr.status === 500) {
reject(new Error('404 not found'))
}
}
}
xhr.send(null)
})
return p
}
const url = '/data/test.json'
ajax(url)
.then(res => console.log(res))
.catch(err => console.error(err))
Promise加载一张图片
function loadImg(src) {
const p = new Promise(
(resolve, reject) => {
const img = document.createElement('img')
img.onload = () => {
resolve(img)
}
img.onerror = () => {
const err = new Error(`图片加载失败 ${src}`)
reject(err)
}
img.src = src
}
)
return p
}
const url1 = 'https://img.mukewang.com/5a9fc8070001a82402060220-140-140.jpg'
const url2 = 'https://img3.mukewang.com/5a9fc8070001a82402060220-100-100.jpg'
loadImg(url1).then(img1 => {
console.log(img1.width)
return img1
}).then(img1 => {
console.log(img1.height)
return loadImg(url2)
}).then(img2 => {
console.log(img2.width)
return img2
}).then(img2 => {
console.log(img2.height)
}).catch(ex => console.error(ex))