生成UUID 1 2 3 4 5 6 7 function S4 ( ) { return (((1 +Math .random ())*0x10000 )|0 ).toString (16 ).substring (1 ); } export const getUUID = ( ) => { return (S4 ()+S4 ()+"-" +S4 ()+"-" +S4 ()+"-" +S4 ()+"-" +S4 ()+S4 ()+S4 ()); }
ArrayBuffer to Base 64 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 export const arraybufferToBase64 = ( buffer ) => { if ( !buffer ) return const str = String .fromCharCode (...new Uint8Array (buffer)); return `data:image/jpeg;base64,${btoa(str)} ` ; }
判断是否为空 1 2 3 4 export const isEmpty = ( obj ) => { if ( typeof obj === 'number' && ( obj === 0 || obj === '0' ) ) return false return typeof obj === 'undefined' || !obj || JSON .stringify (obj) === '{}' || obj === 'null' }
判断RGB颜色 深浅 1 2 3 4 5 6 7 8 9 10 11 export const colorDepth = ( R,G,B ) => { let r = Number (R.replace (/[^0-9]/ig ,"" )) || 255 let g = Number (G) || 255 let b = Number (B) || 255 const computedColorVal = r*0.299 + g*0.578 + b*0.114 if ( computedColorVal >= 192 ){ return 'light' } return 'dark' }
16进制颜色转换RGB 1 2 3 4 export const hex2Rgba = (hex = '#2c4dae' , opacity ) => { return "rgba(" + parseInt ("0x" + hex.slice (1 , 3 )) + "," + parseInt ("0x" + hex.slice (3 , 5 )) + "," + parseInt ("0x" + hex.slice (5 , 7 )) + "," + (opacity || "1" ) + ")" ; }
数组对象去重 1 2 3 4 5 6 7 8 9 10 11 12 13 export const toRepetitionByObj = function ( arr, repetitionItem ) { if ( !isArray (arr) || !arr.length ) return [] let obj = {} return arr.reduce ((cur,next ) => { obj[next[repetitionItem]] ? "" : obj[next[repetitionItem]] = true && cur.push (next); return cur; },[]) }
判断是不是函数 1 2 3 export function isFunction (fn ) { return Object .prototype .toString .call (fn) === '[object Function]' ; }
判断是不是数组 1 2 3 4 export const isArray = ( arr = [] ) => { if ( !arr ) return arr return Object .prototype .toString .apply (arr) === '[object Array]' }
判断是不是对象 1 2 3 export const isObject = ( obj = {} ) => { return Object .prototype .toString .call (obj) === '[object Object]' }
判断是否 Promise 1 2 3 export function isPromise (obj ) { return !!obj && (typeof obj === 'object' || typeof obj === 'function' ) && typeof obj.then === 'function' ; }
格式化日期 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 export function formatDate (date, fmt = 'yyyy-MM-dd hh:mm:ss' ) { if (typeof date === 'string' ) { if (fmt.indexOf ('hh:mm:ss' ) > -1 ) { let newDate = new Date (); let minutes = newDate.getMinutes () < 9 ? `0${newDate.getMinutes()} ` : `${newDate.getMinutes()} ` return `${date} ${newDate.getHours()} :${ minutes } :${newDate.getSeconds()} ` ; } return date; } if (!date || date == null ) return null ; let o = { 'M+' : date.getMonth () + 1 , 'd+' : date.getDate (), 'h+' : date.getHours (), 'm+' : date.getMinutes (), 's+' : date.getSeconds (), 'q+' : Math .floor ((date.getMonth () + 3 ) / 3 ), 'S' : date.getMilliseconds () } if (/(y+)/ .test (fmt)) { fmt = fmt.replace (RegExp .$1 , (date.getFullYear () + '' ).substr (4 - RegExp .$1 .length )) } for (let k in o) { if (new RegExp ('(' + k + ')' ).test (fmt)) { fmt = fmt.replace (RegExp .$1 , (RegExp .$1 .length === 1 ) ? (o[k]) : (('00' + o[k]).substr (('' + o[k]).length ))) } } return fmt }
生成自定义数组数据 1 2 3 4 5 6 7 8 9 export const getOptionsData = ( ) => { return Array .from ({length :100 }, (v,k ) => k).reduce ( (prev, current ) => { return prev = prev.concat ({ id : current, label : `${current} -data` , value : current }) }, []); }
判断两个时间区间是否重叠 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 const checkTimeOverlap = (timeA, timeB ) => { if (!Array .isArray (timeA) || !Array .isArray (timeB)) return false const maxA = new Date (timeA[0 ]).getTime () const maxB = new Date (timeB[0 ]).getTime () const minA = new Date (timeA[1 ]).getTime () const minB = new Date (timeB[1 ]).getTime () const max = [maxA, maxB]; const min = [minA, minB]; console .log ('timeA, timeB' , timeA[0 ], timeB[0 ]) console .log ('max, min' , max, min) return (Math .max .apply (null , max) <= Math .min .apply (null , min)) } let a1 = ['2022-10-28 08:00:00' , '2022-10-28 22:00:00' ]let a2 = ['2022-10-28 10:19:00' , '2022-10-28 23:19:00' ]let result = checkTimeOverlap (a1, a2)console .log ('result' , result)
点击全屏 1 2 3 4 5 6 export function fullScreen ( ) { var el = document .documentElement ; el.requestFullscreen ||el.mozRequestFullScreen ||el.webkitRequestFullscreen ||el.msRequestFullScreen ? el.requestFullscreen ()||el.mozRequestFullScreen ()|| el.webkitRequestFullscreen ()||el.msRequestFullscreen ():null ; }
clone 复制 1 2 3 4 5 6 7 8 9 10 11 12 13 export const clone = ( obj ) => { if ( isArray (obj) || isObject (obj) ) { return JSON .parse (JSON .stringify (obj, function (key, value ) { if ( isFunction ( value ) ) { return Function .prototype .toString .call (value) } return value })) } return {} }
a标签实现文件下载 1 2 3 4 5 6 7 8 9 10 11 export function downloadFile (blobFile, filename ) { const blobUrl = URL .createObjectURL (blobFile) const aDom = document .createElement ('a' ) aDom.href = blobUrl aDom.download = filename aDom.click () document .removeChild (aDom) URL .revokeObjectURL (blobUrl) }
arrayBuffer 转换 Json 1 2 3 4 5 6 7 8 export function arrayBufferToJson ( arrayBufferData ){ let enc = new TextDecoder ("utf-8" ); let uint8_msg = new Uint8Array (arrayBufferData); let jsonData = JSON .parse (enc.decode (uint8_msg)); console .log (jsonData); }
根据dom的Id滚动到对应元素的位置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 function scrollToId (id ) { const element = document .getElementById (id); const offset = element.offsetTop ; const duration = 600 ; let start = null ; function animation (timestamp ) { if (!start) start = timestamp; const progress = timestamp - start; window .scrollTo (0 , offset * progress / duration); if (progress < duration) { window .requestAnimationFrame (animation); } } window .requestAnimationFrame (animation); }
判断一个元素是否在可视区域内 1 使用addEventListener scroll
getBoundingClientRect 当页面发生滚动的时候,top与left属性值都会随之改变 如果一个元素在视窗之内的话,那么它一定满足下面四个条件: top 大于等于 0 left 大于等于 0 bottom 小于等于视窗高度 right 小于等于视窗宽度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 let targetEl = document .querySelector ('#app-main' )targetEl.addEventListener ('scroll' , mainListenerScroll, true ) function isInViewPort (element ) { const viewWidth = window .innerWidth || document .documentElement .clientWidth ; const viewHeight = window .innerHeight || document .documentElement .clientHeight ; const { top, right, bottom, left } = element.getBoundingClientRect (); return top >= 0 && left >= 0 && right <= viewWidth && bottom <= viewHeight; } function mainListenerScroll (e ) { let a = isInViewPort (currentEl) } targetEl.removeEventListener ('scroll' , mainListenerScroll,true )
判断一个元素是否在可视区域内 2 使用IntersectionObserver
创建一个新的 IntersectionObserver 对象,当其监听到目标元素的可见部分(的比例)超过了一个或多个阈值(threshold)时,会执行指定的回调函数。
1 2 3 4 5 6 7 8 9 10 11 12 let intersectionObserver = new IntersectionObserver (getYellow, { threshold : 1.0 });let targetEl = document .querySelector ('#app-main' )intersectionObserver.observe (targetEl) IntersectionObserver .unobserve ()IntersectionObserver .disconnect ()intersectionObserver = null
分组 1 2 3 4 5 6 7 8 9 10 11 export function groupBy ( arr, prop ){ let groupByResult = {}; for (let item of arr) { let key = item[prop]; if (!groupByResult[key]) { groupByResult[key] = []; } groupByResult[key].push (item) } }
高级分组 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 let arr1 = [2 ,4 ,5 ,5 ,6 ,1 ,2 ]let arr2 = [{ name : "ali" , sex : "18" },{ name : "ali" , sex : "18" },{ name : "boo" , sex : "28" },{ name : "boo" , sex : "28" }]export function groupBy ( arr, generatorKey ){ let groupByResult = {}; for (let item of arr) { let key = generatorKey (item) if (!groupByResult[key]) { groupByResult[key] = []; } groupByResult[key].push (item) } } groupBy (arr1, (item ) => item)groupBy (arr2, (item ) => item.name )
重写toFixed 1 2 3 4 5 6 Number .prototype .toFixed = function (d ) { return (Math .round (Number (this ) * Math .pow (10 , d)) / Math .pow (10 , d)).toString (); }
重写replace 1 2 3 String .prototype .replaceAll = function (s1, s2 ) { return this .replace (new RegExp (s1, "gm" ), s2); }