
作者:叫我詹躲躲
转发链接:
https://juejin.im/post/5edb6c6be51d4578a2555a9b
131.file转base64
| |
| |
| |
| export const fileToBase64 = file => { |
| let reader = new FileReader(); |
| reader.readAsDataURL(file); |
| reader.onload = function (e) { |
| return e.target.result |
| }; |
| }; |
132.递归生成树形结构
| export function getTreeData(data, pid, pidName = 'parentId', idName = 'id', childrenName = 'children', key) { |
| let arr = []; |
| |
| for (let i = 0; i < data.length; i++) { |
| if (data[i][pidName] == pid) { |
| data[i].key = data[i][idName]; |
| data[i][childrenName] = getTreeData(data, data[i][idName], pidName, idName, childrenName); |
| arr.push(data[i]); |
| } |
| } |
| |
| return arr; |
| |
| } |
133.遍历树节点
| export function foreachTree(data, childrenName = 'children', callback) { |
| for (let i = 0; i < data.length; i++) { |
| callback(data[i]); |
| if (data[i][childrenName] && data[i][childrenName].length > 0) { |
| foreachTree(data[i][childrenName], childrenName, callback); |
| } |
| } |
| } |
134.追溯父节点
| export function traceParentNode(pid, data, rootPid, pidName = 'parentId', idName = 'id', childrenName = 'children') { |
| let arr = []; |
| foreachTree(data, childrenName, (node) => { |
| if (node[idName] == pid) { |
| arr.push(node); |
| if (node[pidName] != rootPid) { |
| arr = arr.concat(traceParentNode(node[pidName], data, rootPid, pidName, idName)); |
| } |
| } |
| }); |
| return arr; |
| } |
135.寻找所有子节点
| export function traceChildNode(id, data, pidName = 'parentId', idName = 'id', childrenName = 'children') { |
| let arr = []; |
| foreachTree(data, childrenName, (node) => { |
| if (node[pidName] == id) { |
| arr.push(node); |
| arr = arr.concat(traceChildNode(node[idName], data, pidName, idName, childrenName)); |
| } |
| }); |
| return arr; |
| } |
136.根据pid生成树形结构
| |
| |
| |
| |
| |
| export const createTree = (items, id = null, link = 'pid') =>{ |
| items.filter(item => item[link] === id).map(item => ({ ...item, children: createTree(items, item.id) })); |
| }; |
137.查询数组中是否存在某个元素并返回元素第一次出现的下标
| |
| |
| |
| |
| export function inArray(item, data) { |
| for (let i = 0; i < data.length; i++) { |
| if (item === data[i]) { |
| return i; |
| } |
| } |
| return -1; |
| } |
138.Windows根据详细版本号判断当前系统名称
| |
| |
| |
| export function OutOsName(osVersion) { |
| if(!osVersion){ |
| return |
| } |
| let str = osVersion.substr(0, 3); |
| if (str === "5.0") { |
| return "Win 2000" |
| } else if (str === "5.1") { |
| return "Win XP" |
| } else if (str === "5.2") { |
| return "Win XP64" |
| } else if (str === "6.0") { |
| return "Win Vista" |
| } else if (str === "6.1") { |
| return "Win 7" |
| } else if (str === "6.2") { |
| return "Win 8" |
| } else if (str === "6.3") { |
| return "Win 8.1" |
| } else if (str === "10.") { |
| return "Win 10" |
| } else { |
| return "Win" |
| } |
| } |
139.判断手机是Andoird还是IOS
| |
| |
| |
| |
| |
| export function getOSType() { |
| let u = navigator.userAgent, app = navigator.appVersion; |
| let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; |
| let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); |
| if (isIOS) { |
| return 0; |
| } |
| if (isAndroid) { |
| return 1; |
| } |
| return 2; |
| } |
140.函数防抖
| /** |
| * @param { function } func |
| |
| * @param { number } wait 延迟执行毫秒数 |
| |
| * @param { boolean } immediate true 表立即执行,false 表非立即执行 |
| */ |
| export function debounce(func,wait,immediate) { |
| let timeout; |
| return function () { |
| let context = this; |
| let args = arguments; |
| |
| if (timeout) clearTimeout(timeout); |
| if (immediate) { |
| let callNow = !timeout; |
| timeout = setTimeout(() => { |
| timeout = null; |
| }, wait); |
| if (callNow) func.apply(context, args) |
| } else { |
| timeout = setTimeout(() => { |
| func.apply(context, args) |
| }, wait); |
| } |
| |
| } |
| } |
145.函数节流
| /** |
| * @param { function } func 函数 |
| * @param { number } wait 延迟执行毫秒数 |
| * @param { number } type 1 表时间戳版,2 表定时器版 |
| */ |
| export function throttle(func, wait ,type) { |
| let previous, timeout; |
| if(type===1){ |
| previous = 0; |
| }else if(type===2){ |
| timeout = null; |
| } |
| return function() { |
| let context = this; |
| let args = arguments; |
| if(type===1){ |
| let now = Date.now(); |
| if (now - previous > wait) { |
| func.apply(context, args); |
| previous = now; |
| } |
| }else if(type===2){ |
| if (!timeout) { |
| timeout = setTimeout(() => { |
| timeout = null; |
| func.apply(context, args) |
| }, wait) |
| } |
| } |
| } |
| } |
146.判断数据类型
| |
| |
| |
| export function type(target) { |
| let ret = typeof(target); |
| let template = { |
| "[object Array]": "array", |
| "[object Object]":"object", |
| "[object Number]":"number - object", |
| "[object Boolean]":"boolean - object", |
| "[object String]":'string-object' |
| }; |
| |
| if(target === null) { |
| return 'null'; |
| }else if(ret == "object"){ |
| let str = Object.prototype.toString.call(target); |
| return template[str]; |
| }else{ |
| return ret; |
| } |
| } |
147.生成指定范围随机数
| /** |
| * @param { number } min |
| * @param { number } max |
| */ |
| export const RandomNum = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; |
148.数组乱序
| |
| |
| |
| export function arrScrambling(arr) { |
| let array = arr; |
| let index = array.length; |
| while (index) { |
| index -= 1; |
| let randomIndex = Math.floor(Math.random() * index); |
| let middleware = array[index]; |
| array[index] = array[randomIndex]; |
| array[randomIndex] = middleware |
| } |
| return array |
| } |
150.数组交集
| |
| |
| |
| |
| export const similarity = (arr1, arr2) => arr1.filter(v => arr2.includes(v)); |
151.数组中某元素出现的次数
| |
| |
| |
| |
| |
| export function countOccurrences(arr, value) { |
| return arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0); |
| } |
152.加法函数(精度丢失问题)
| |
| |
| |
| |
| export function add(arg1, arg2) { |
| let r1, r2, m; |
| try { r1 = arg1.toString().split(".")[1].length } catch (e) { r1 = 0 } |
| try { r2 = arg2.toString().split(".")[1].length } catch (e) { r2 = 0 } |
| m = Math.pow(10, Math.max(r1, r2)); |
| return (arg1 * m + arg2 * m) / m |
| } |
153.减法函数(精度丢失问题)
| |
| |
| |
| |
| export function sub(arg1, arg2) { |
| let r1, r2, m, n; |
| try { r1 = arg1.toString().split(".")[1].length } catch (e) { r1 = 0 } |
| try { r2 = arg2.toString().split(".")[1].length } catch (e) { r2 = 0 } |
| m = Math.pow(10, Math.max(r1, r2)); |
| n = (r1 >= r2) ? r1 : r2; |
| return Number(((arg1 * m - arg2 * m) / m).toFixed(n)); |
| } |
154.除法函数(精度丢失问题)
| |
| |
| |
| |
| export function division(num1,num2){ |
| let t1,t2,r1,r2; |
| try{ |
| t1 = num1.toString().split('.')[1].length; |
| }catch(e){ |
| t1 = 0; |
| } |
| try{ |
| t2=num2.toString().split(".")[1].length; |
| }catch(e){ |
| t2=0; |
| } |
| r1=Number(num1.toString().replace(".","")); |
| r2=Number(num2.toString().replace(".","")); |
| return (r1/r2)*Math.pow(10,t2-t1); |
| } |
155.乘法函数(精度丢失问题)
| |
| |
| |
| |
| export function mcl(num1,num2){ |
| let m=0,s1=num1.toString(),s2=num2.toString(); |
| try{m+=s1.split(".")[1].length}catch(e){} |
| try{m+=s2.split(".")[1].length}catch(e){} |
| return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m); |
| } |
156.递归优化(尾递归)
| |
| |
| |
| export function tco(f) { |
| let value; |
| let active = false; |
| let accumulated = []; |
| |
| return function accumulator() { |
| accumulated.push(arguments); |
| if (!active) { |
| active = true; |
| while (accumulated.length) { |
| value = f.apply(this, accumulated.shift()); |
| } |
| active = false; |
| return value; |
| } |
| }; |
| } |
157.生成随机整数
| export function randomNumInteger(min, max) { |
| switch (arguments.length) { |
| case 1: |
| return parseInt(Math.random() * min + 1, 10); |
| case 2: |
| return parseInt(Math.random() * (max - min + 1) + min, 10); |
| default: |
| return 0 |
| } |
| } |
158.去除空格
| |
| |
| |
| |
| export function trim(str, type = 1) { |
| if (type && type !== 1 && type !== 2 && type !== 3 && type !== 4) return; |
| switch (type) { |
| case 1: |
| return str.replace(/\s/g, ""); |
| case 2: |
| return str.replace(/(^\s)|(\s*$)/g, ""); |
| case 3: |
| return str.replace(/(^\s)/g, ""); |
| case 4: |
| return str.replace(/(\s$)/g, ""); |
| default: |
| return str; |
| } |
| } |
159.大小写转换
| |
| |
| |
| |
| |
| export function turnCase(str, type) { |
| switch (type) { |
| case 1: |
| return str.toUpperCase(); |
| case 2: |
| return str.toLowerCase(); |
| case 3: |
| return str[0].toUpperCase() + str.substr(1).toLowerCase(); |
| default: |
| return str; |
| } |
| } |
160.随机16进制颜色 hexColor
| |
| |
| |
| export function hexColor() { |
| |
| let str = '#'; |
| let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'A', 'B', 'C', 'D', 'E', 'F']; |
| for (let i = 0; i < 6; i++) { |
| let index = Number.parseInt((Math.random() * 16).toString()); |
| str += arr[index] |
| } |
| return str; |
| } |
161.随机16进制颜色 randomHexColorCode
| |
| |
| |
| export const randomHexColorCode = () => { |
| let n = (Math.random() * 0xfffff * 1000000).toString(16); |
| return '#' + n.slice(0, 6); |
| }; |
162.转义html(防XSS攻击)
| export const escapeHTML = str =>{ |
| str.replace( |
| /[&<>'"]/g, |
| tag => |
| ({ |
| '&': '&', |
| '<': '<', |
| '>': '>', |
| "'": ''', |
| '"': '"' |
| }[tag] || tag) |
| ); |
| }; |
| |
163.检测移动/PC设备
| export const detectDeviceType = () => { |
| return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ? 'Mobile' : 'Desktop'; |
| }; |
164.隐藏所有指定标签
| |
| |
| |
| export const hideTag = (...el) => [...el].forEach(e => (e.style.display = 'none')); |
165.返回指定元素的生效样式
| |
| |
| |
| |
| export const getStyle = (el, ruleName) => getComputedStyle(el)[ruleName]; |
166.检查是否包含子元素
| |
| |
| |
| |
| |
| export const elementContains = (parent, child) => parent !== child && parent.contains(child); |
167.数字超过规定大小加上加号“+”,如数字超过99显示99+
| |
| |
| |
| |
| export const outOfNum = (val, maxNum) =>{ |
| val = val ? val-0 :0; |
| if (val > maxNum ) { |
| return `${maxNum}+` |
| }else{ |
| return val; |
| } |
| }; |
168.如何隐藏所有指定的元素
| const hide = (el) => Array.from(el).forEach(e => (e.style.display = 'none')); |
| |
| |
| hide(document.querySelectorAll('img')) |
169.如何检查元素是否具有指定的类?
页面DOM里的每个节点上都有一个classList对象,程序员可以使用里面的方法新增、删除、修改节点上的CSS类。使用classList,程序员还可以用它来判断某个节点是否被赋予了某个CSS类。
| const hasClass = (el, className) => el.classList.contains(className) |
| |
| |
| hasClass(document.querySelector('p.special'), 'special') |
170.如何切换一个元素的类?
| const toggleClass = (el, className) => el.classList.toggle(className) |
| |
| |
| toggleClass(document.querySelector('p.special'), 'special') |
171.如何获取当前页面的滚动位置?
| const getScrollPosition = (el = window) => ({ |
| x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft, |
| y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop |
| }); |
| |
| // 事例 |
| getScrollPosition(); // {x: 0, y: 200} |
172.如何平滑滚动到页面顶部
| const scrollToTop = () => { |
| const c = document.documentElement.scrollTop || document.body.scrollTop; |
| if (c > 0) { |
| window.requestAnimationFrame(scrollToTop); |
| window.scrollTo(0, c - c / 8); |
| } |
| } |
| |
| |
| scrollToTop() |
| |
| window.requestAnimationFrame() |
requestAnimationFrame:优势:由系统决定回调函数的执行时机。60Hz的刷新频率,那么每次刷新的间隔中会执行一次回调函数,不会引起丢帧,不会卡顿。
window.requestAnimationFrame()
requestAnimationFrame:优势:由系统决定回调函数的执行时机。60Hz的刷新频率,那么每次刷新的间隔中会执行一次回调函数,不会引起丢帧,不会卡顿。
173.如何检查父元素是否包含子元素?
| const elementContains = (parent, child) => parent !== child && parent.contains(child); |
| |
| |
| elementContains(document.querySelector('head'), document.querySelector('title')); |
| |
| elementContains(document.querySelector('body'), document.querySelector('body')); |
| |
174.如何检查指定的元素在视口中是否可见?
| const elementIsVisibleInViewport = (el, partiallyVisible = false) => { |
| const { top, left, bottom, right } = el.getBoundingClientRect(); |
| const { innerHeight, innerWidth } = window; |
| return partiallyVisible |
| ? ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)) && |
| ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth)) |
| : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth; |
| }; |
| |
| |
| elementIsVisibleInViewport(el); |
| elementIsVisibleInViewport(el, true); |
175.如何获取元素中的所有图像?
| const getImages = (el, includeDuplicates = false) => { |
| const images = [...el.getElementsByTagName('img')].map(img => img.getAttribute('src')); |
| return includeDuplicates ? images : [...new Set(images)]; |
| }; |
| |
| |
| getImages(document, true); |
| getImages(document, false); |
细品269个JavaScript小函数,让你少加班熬夜(一)「值得收藏」
细品269个JavaScript小函数,让你少加班熬夜(二)「值得收藏」
细品269个JavaScript小函数,让你少加班熬夜(三)「值得收藏」
细品269个JavaScript小函数,让你少加班熬夜(四)「值得收藏」
细品269个JavaScript小函数,让你少加班熬夜(五)「值得收藏」
细品269个JavaScript小函数,让你少加班熬夜(六)「值得收藏」