生成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
// Uint8Array 表示8位无符号整数数组
// String.fromCharCode这个函数,它接受的参数为一堆代码单元序列,输出一个普通字符串
const str = String.fromCharCode(...new Uint8Array(buffer));
// btoa 把一个普通字符串编码成base-64格式的字符串。
return `data:image/jpeg;base64,${btoa(str)}`;

/* let binary = '';
let bytes = new Uint8Array(buffer);
let len = bytes.byteLength;
for (let i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);*/
}

判断是否为空

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 ) => {
// if ( !R && !G && !B ) return ''
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) => {
// if(!hex) hex = "#2c4dae";
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
/**
* 数组对象去重
* param:1 数组对象
* param:2 去重项标识
* */
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
/**
* 判断两个时间区间是否重叠
* @params timeA array[startTimeString,startTimeString]
* @params timeB array[startTimeString,startTimeString]
* @return boolean
* */
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() {
// documentElement 属性以一个元素对象返回一个文档的文档元素
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) {
// console.log(key, value)
if ( isFunction( value ) ) {
// console.log('clone isFunction value',key, 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) {
// 创建 blobUrl 该 Url会占用内存
const blobUrl = URL.createObjectURL(blobFile)
const aDom = document.createElement('a')
aDom.href = blobUrl
aDom.download = filename
aDom.click()
document.removeChild(aDom)
// 释放 URL
URL.revokeObjectURL(blobUrl)
}

arrayBuffer 转换 Json

1
2
3
4
5
6
7
8
export function arrayBufferToJson( arrayBufferData ){
// 使用TextDecoder
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)
}

// unbind 的时候卸载监听器
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)

// unbind 清除对象
//使 IntersectionObserver 对象停止监听目标。
IntersectionObserver.unobserve()
// 使 IntersectionObserver 对象停止监听目标。
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 = item[prop];
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);
}