JS工具类常用方法
/**
* 绘制圆角矩形
* @param {Object} ctx - canvas组件的绘图上下文
* @param {Number} x - 矩形的x坐标
* @param {Number} y - 矩形的y坐标
* @param {Number} w - 矩形的宽度
* @param {Number} h - 矩形的高度
* @param {Number} r - 矩形的圆角半径
* @param {String} [c = 'transparent'] - 矩形的填充色
*/
export function roundRect(ctx, x, y, w, h, r, c = '#fff') {
if (w < 2 * r) r = w / 2;
if (h < 2 * r) r = h / 2;
ctx.beginPath();
ctx.fillStyle = c;
ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5);
ctx.moveTo(x + r, y);
ctx.lineTo(x + w - r, y);
ctx.lineTo(x + w, y + r);
ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2);
ctx.lineTo(x + w, y + h - r);
ctx.lineTo(x + w - r, y + h);
ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5);
ctx.lineTo(x + r, y + h);
ctx.lineTo(x, y + h - r);
ctx.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI);
ctx.lineTo(x, y + r);
ctx.lineTo(x + r, y);
ctx.fill();
ctx.closePath();
}
/**
* 绘制上左上右两个圆角图片
* @param {Object} ctx - canvas组件的绘图上下文
* @param {String} img - 图片
* @param {Number} x - 图片的x坐标
* @param {Number} y - 图片的y坐标
* @param {Number} width - 图片的宽度
* @param {Number} height - 图片的高度
* @param {Number} r - 图片的圆角半径
*/
export function imgfillet(ctx, img, x, y, width, height, r) {
if (width < 2 * r) r = width / 2;
if (height < 2 * r) r = height / 2;
ctx.beginPath();
ctx.save();
ctx.setLineWidth(1);
ctx.setStrokeStyle('#ffffff');
ctx.moveTo(x + r, y); // 创建开始点
ctx.lineTo(x + width - r, y); // 创建水平线
ctx.arcTo(x + width, y, x + width, y + r, r); // 右上角创建弧
ctx.lineTo(x + width, y + height); // 创建垂直线
ctx.lineTo(x + r, y + height); // 创建水平线
ctx.lineTo(x, y + height); // 创建垂直线
ctx.arcTo(x, y, x + r, y, r); // 左上角创建弧
ctx.stroke(); // 画出当前路径的边框
ctx.clip(); //剪切
ctx.drawImage(img, x, y, width, height);
ctx.restore();
ctx.closePath();
}
/**
* 绘制四个圆角图片
* @param {Object} ctx - canvas组件的绘图上下文
* @param {String} img - 图片
* @param {Number} x - 图片的x坐标
* @param {Number} y - 图片的y坐标
* @param {Number} width - 图片的宽度
* @param {Number} height - 图片的高度
* @param {Number} r - 图片的圆角半径
*/
export function imageRound(ctx, img, x, y, width, height, r) {
if (width < 2 * r) r = width / 2;
if (height < 2 * r) r = height / 2;
ctx.beginPath();
ctx.save();
ctx.setLineWidth(1);
ctx.setStrokeStyle('#ffffff');
ctx.moveTo(x + r, y); // 创建开始点
ctx.lineTo(x + width - r, y); // 创建水平线
ctx.arcTo(x + width, y, x + width, y + r, r); // 右上角创建弧
ctx.lineTo(x + width, y + height - r); // 创建垂直线
ctx.arcTo(x + width, y + height, x + width - r, y + height, r); // 右下角创建弧
ctx.lineTo(x + r, y + height); // 创建水平线
ctx.arcTo(x, y + height, x, y + height - r, r); // 左下角创建弧
ctx.lineTo(x, y + r); // 创建垂直线
ctx.arcTo(x, y, x + r, y, r); // 左上角创建弧
ctx.stroke(); // 画出当前路径的边框
ctx.clip(); //剪切
ctx.drawImage(img, x, y, width, height);
ctx.restore();
ctx.closePath();
}
/**
* 字符串中间几位修改为*号
* @param {String} str - 操作字符串
* @param {Number} start - 开头不需要变成星号的长度
* @param {Number} end - 末尾不需要变成星号的长度,设置默认值为0, 不传就除了设置的开头几位剩余全部变成星号
*/
export function changeToStar(str, start, end = 0) {
let strLen = str.length;
let stars = ''
for (let i = 0; i < strLen - start - end; i++) {
stars += '*'
}
str = str.substr(0, start) + stars + str.substr(strLen - end);
return str;
}
/**
* 获取当前日期N天后的日期
* @param {Number} AddDayCount - 天数
*/
export function getDateStr(AddDayCount) {
var dd = new Date();
dd.setDate(dd.getDate() + AddDayCount); //获取AddDayCount天后的日期
var y = dd.getFullYear();
var m = (dd.getMonth() + 1) < 10 ? "0" + (dd.getMonth() + 1) : (dd.getMonth() + 1); //获取当前月份的日期,不足10补0
var d = dd.getDate() < 10 ? "0" + dd.getDate() : dd.getDate(); //获取当前几号,不足10补0
return y + "-" + m + "-" + d;
}
/**
* 获取当前日期的N天前后的日期数组 日期格式2020-07-23
* @param {Number} num - 天数
*/
export function getAllDate(num) {
var today = new Date();
var dateArr = [];
for (var i = 1; i < num; i++) {
var newDate = new Date(today.getTime() - i * 1000 * 60 * 60 * 24); // N天前
var year = newDate.getFullYear();
var month = (parseInt(newDate.getMonth()) + 1) > 9 ? (parseInt(newDate.getMonth()) + 1) : "0" + (parseInt(
newDate.getMonth()) + 1);
var day = (newDate.getDate()) > 9 ? newDate.getDate() : "0" + newDate.getDate();
var fullDate = `${year}-${month}-${day}`;
dateArr.unshift(fullDate);
}
for (var i = 0; i < num; i++) {
var newDate = new Date(today.getTime() + i * 1000 * 60 * 60 * 24); // N天后
var year = newDate.getFullYear();
var month = (parseInt(newDate.getMonth()) + 1) > 9 ? (parseInt(newDate.getMonth()) + 1) : "0" + (parseInt(
newDate.getMonth()) + 1);
var day = (newDate.getDate()) > 9 ? newDate.getDate() : "0" + newDate.getDate();
var fullDate = `${year}-${month}-${day}`;
dateArr.push(fullDate);
}
return dateArr;
}
/**
* 获取当期日期是星期几 日期格式2020-07-23
* @param {String} datestr - 日期
*/
export function getDateIsweek(datestr) {
var weekArray = new Array("周日", "周一", "周二", "周三", "周四", "周五", "周六");
var week = weekArray[new Date(datestr).getDay()];
return week;
}
/**
* 格式化时间戳为日期
* @param {*} date 传入一个时间
* @param {*} fmt 时间格式
* @param {*} defaultValue 默认值
* @return 日期字符串
*/
export function dateFormat(date, fmt = "yyyy-MM-dd HH:mm:ss", defaultValue = "") {
if (!date) {
return defaultValue;
}
if (typeof date === "string") {
date = new Date(date.replace(/-/g, "/"));
} else {
date = new Date(date);
}
var 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 (var 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;
}
/**
* 格式化时间戳为字符串日期
* @param {(Object|string|number)} time
* @param {string} cFormat
* @return {string | null}
*/
export function parseTime(time, cFormat) {
if (arguments.length === 0 || !time) {
return null
}
const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if ((typeof time === 'string')) {
if ((/^[0-9]+$/.test(time))) {
// support "1548221490638"
time = parseInt(time)
} else {
time = time.replace(new RegExp(/-/gm), '/')
}
}
if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
const value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
return value.toString().padStart(2, '0')
})
return time_str
}
/**
* 深拷贝对象
* @param {Object} obj 需要拷贝的对象
* @return 拷贝对象
*/
export function deepClone(obj) {
const _toString = Object.prototype.toString
// null, undefined, non-object, function
if (!obj || typeof obj !== 'object') {
return obj
}
// DOM Node
if (obj.nodeType && 'cloneNode' in obj) {
return obj.cloneNode(true)
}
// Date
if (_toString.call(obj) === '[object Date]') {
return new Date(obj.getTime())
}
// RegExp
if (_toString.call(obj) === '[object RegExp]') {
const flags = []
if (obj.global) { flags.push('g') }
if (obj.multiline) { flags.push('m') }
if (obj.ignoreCase) { flags.push('i') }
return new RegExp(obj.source, flags.join(''))
}
const result = Array.isArray(obj) ? [] : obj.constructor ? new obj.constructor() : { }
for (const key in obj) {
result[key] = deepClone(obj[key])
}
return result
}
/**
* 提取地址栏参数
* @param {string} name 需要获取的参数名
* @param {string} src 获取的url地址
* @return 参数值 {string}
*/
export function getUrlArgument(name, src) {
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)')
.exec(src) || [, ''])[1]
.replace(/\+/g, '%20')) || null
}
/**处理小程序海报网络图片,base64图片 **/
const fsm = wx.getFileSystemManager();
const FILE_BASE_NAME = 'file_base64src'; //自定义文件名
/**
* 删除本地同名文件
* @params {string} 删除文件后缀名
**/
export function removeSave(format = 'png') {
return new Promise((resolve) => {
const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.${format}`;
fsm.unlink({
filePath: filePath,
success(res) {
console.log('文件删除成功');
resolve(true);
},
fail(e) {
console.log('readdir文件删除失败:', e);
resolve(true);
}
});
})
}
/**
* 将base64图片,存储到本地,生成临时url
* @params {string} base64
* @return {string} 临时url
**/
export function base64ToSave(base64data) {
return new Promise((resolve) => {
const [, format] = /data:image\/(\w+);base64,/.exec(base64data) || [];
const bodyData = base64data.replace(/^data:image\/\w+;base64,/, "");
if (!format) {
return (new Error('ERROR_BASE64SRC_PARSE'));
}
const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.${format}`;
const buffer = wx.base64ToArrayBuffer(bodyData);
fsm.writeFile({
filePath,
data: buffer,
encoding: 'binary',
success() {
resolve(filePath);
},
fail() {
return (new Error('ERROR_BASE64SRC_WRITE'));
},
});
})
}
/**下载后台返回的文件流 **/
let link = document.createElement('a');
let filename = res.headers['content-disposition'].split('=')[1]; //文件名
filename = decodeURI(filename); //将文件名转码成中文
let blob = new Blob([res.data], {type: res.headers['content-type']}); //将文件流转换成blob对象
link.style.display = 'none';
link.href = URL.createObjectURL(blob); //文件地址
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
/** 操作普通数组 **/
let arr = [1, 2]
let num = [{name: '1', id:1}, {name: '2', id: 2}, {name: '4', id: 4}]
let array = num.filter(val => arr.indexOf(val['id']) > -1)
console.log(array) // [{name: '1', id:1}, {name: '2', id: 2}]
let arr = [1, 2, 3, 4]
let array = [3, 4, 5, 6]
// 交集
let jiao = arr.filter(item => array.indexOf(item) > -1)
console.log(jiao) //[1, 2]
// 并集
let bing = arr.concat(array.filter(item => !(arr.indexOf(item) > -1)))
console.log(bing) // [1, 2, 3, 4, 5, 6]
// 补集 两个数组都没有的
let bu = arr.filter(item => !(array.indexOf(item) > -1)).concat(array.filter(item => !(arr.indexOf(item) > -1)))
console.log(bu) // [1, 2, 5, 6]
// 差集
let chaArr = arr.filter(item => array.indexOf(item) === -1) //arr与array的差集
console.log(chaArr) //[1, 2]
let chaArray = array.filter(item => arr.indexOf(item) === -1) //array与arr的差集
console.log(chaArray) // [5, 6]
// ES6 Set 对象方法
// add 添加某个值,返回Set对象本身。
// clear 删除所有的键/值对,没有返回值。
// delete 删除某个键,返回true。如果删除失败,返回false。
// forEach 对每个元素执行指定操作。
// has 返回一个布尔值,表示某个键是否在当前 Set 对象之中。
let setArr = [1,2,3,3,1,4];
[...new Set(setArr)]; // [1, 2, 3, 4]
Array.from(new Set(setArr)); // [1, 2, 3, 4]
[...new Set('ababbc')].join(''); // "abc" 字符串去重
let arr = [1, 2, 3, 4]
let array = [3, 4, 5, 6]
// 交集
let jiao = arr.filter(item => new Set(array).has(item))
console.log(jiao); // [3, 4]
// 并集
let bing = Array.from(new Set([...arr, ...array]))
console.log(bing) // [1, 2, 3, 4, 5, 6]
// 补集 两个数组都没有的
let bu = [...arr.filter(item => !(new Set(array).has(item))), ...array.filter(item => !(new Set(arr).has(item)))]
console.log(bu) // [1, 2, 5, 6]
// 差集
let chaArr = arr.filter(item => !(new Set(array).has(item))) //arr与array的差集
let chaArray = array.filter(item => !(new Set(arr).has(item))) //array与arr的差集
console.log(chaArr); // [1, 2]
console.log(chaArray) // [5, 6]
/** 操作对象数组 **/
let arr = [
{id:1, name: "产品1", code: 'c001' },
{id:2, name: "产品2", code: 'c002' },
{id:3, name: "产品3", code: 'c003' },
]
let array = [
{id:3, name: "产品3", code: 'c003' },
{id:4, name: "产品4", code: 'c004' },
{id:5, name: "产品5", code: 'c005' },
]
// 交集
let jiao = [];
for(let i = 0,len = arr.length; i< len; i++) {
for(let j = 0, length = array.length; j < length; j++) {
if(arr[i].id === array[j].id) {
jiao.push(arr[i]);
}
}
}
console.log(jiao) // [{id: 3, name: '产品3', code: 'c003'}]
// 并集
let bing = [...arr, ...array]
for(let i = 0,len = arr.length; i< len; i++) {
for(let j = 0, length = array.length; j < length; j++) {
if(arr[i].id === array[j].id) {
bing.splice(bing.findIndex(item => item.id === arr[i].id), 1)
}
}
}
// [{id: 1, name: '产品1', code: 'c001'},{id: 2, name: '产品2', code: 'c002'},{id: 3, name: '产品3', code: 'c003'},{id: 4, name: '产品4', code: 'c004'},{id: 5, name: '产品5', code: 'c005'}]
console.log(bing)
// 补集 两个数组都没有的
let bu = [...arr, ...array]
for(let i = 0,len = arr.length; i< len; i++) {
for(let j = 0, length = array.length; j < length; j++) {
if(arr[i].id === array[j].id) {
bu.splice(bu.findIndex(item => item.id === arr[i].id), 1)
bu.splice(bu.findIndex(item => item.id === array[j].id), 1)
}
}
}
// [{id: 1, name: '产品1', code: 'c001'},{id: 2, name: '产品2', code: 'c002'},{id: 4, name: '产品4', code: 'c004'},{id: 5, name: '产品5', code: 'c005'}]
console.log(bu)
// 差集
let chaArr = [...arr]
for(let i = 0 , len = arr.length; i < len; i++) {
let flag = false;
for(let j = 0, length = array.length; j < length; j++) {
if(arr[i].id === array[j].id) {
flag = true;
}
}
if(flag) {
chaArr.splice(chaArr.findIndex(item => item.id === arr[i].id), 1)
}
}
console.log(chaArr) //arr与array的差集 [{id: 1, name: '产品1', code: 'c001'},{id: 2, name: '产品2', code: 'c002'}]
let chaArray = [...array]
for(let i = 0 , len = arr.length; i < len; i++) {
let flag = false;
for(let j = 0, length = array.length; j < length; j++) {
if(arr[i].id === array[j].id) {
flag = true;
}
}
if(flag) {
chaArray.splice(chaArray.findIndex(item => item.id === arr[i].id), 1)
}
}
console.log(chaArray) //array与arr的差集 [{id: 4, name: '产品4', code: 'c004'},{id: 5, name: '产品5', code: 'c005'}]
// 获取完整地址栏参数
export const getUrlParams = (url: string, name: string) => {
const reg = new RegExp('(^|&|/?)' + name + '=([^&|/?]*)(&|/?|$)', 'i')
const r = url.substring(1).match(reg)
if (r) return decodeURI(r[2])
return ''
}
// 获取?号后的参数(location.search)
export const getQueryParams = (url: string, name: string) => {
const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i')
const r = url.substring(1).match(reg)
if (r != null) return decodeURI(r[2])
return null
}
// 将一个16进制转10进制数字
export const hex2int = (hex: any) => {
var len = hex.length,
a = new Array(len),
code;
for (var i = 0; i < len; i++) {
code = hex.charCodeAt(i);
if (48 <= code && code < 58) {
code -= 48;
} else {
code = (code & 0xdf) - 65 + 10;
}
a[i] = code;
}
return a.reduce(function (acc, c) {
acc = 16 * acc + c;
return acc;
}, 0);
}
// 获取8字节hex随机数
export const getRamNumber = () => {
let result = '';
for (let i = 0; i < 16; i++) {
result += Math.floor(Math.random() * 16).toString(16);
}
return result.toUpperCase();
}
//转小端 低字节在前,高字节在后
export const dataConversion = (data: any) => {
data = data.replace(/\s/g, '').replace(
/(.{2})/g, "$1 ");
data = data.split(" ").reverse().join("")
return data
}
// 将一串16进制转成对应的10进制数组
export const hex2intArr = (str: string) => {
if (str.length % 2 !== 0) {
console.error('输入的16进制数格式不正确,字符个数不是双数。');
return;
}
const arr = [];
for (let i = 0; i < str.length; i += 2) {
arr.push(hex2int(str.substr(i, 2)));
}
return arr;
};
//str 转 buff
export const str2ab = (str: string) => {
const buffer = new ArrayBuffer(str.length / 2);
let x = new Uint8Array(buffer);
for (let i = 0; i < x.length; i++) {
x[i] = parseInt(str.substr(2 * i, 2), 16)
}
return buffer;
}
/**
* 字符串转arrayBuffer
* @param {*} str 需要转换的字符串
* @returns 返回 arrayBuffer
*/
export const strToArrayBuffer = (str: string) => {
var array = new Uint8Array(str.length);
for (var i = 0; i < str.length; i++) {
array[i] = str.charCodeAt(i);
}
return array.buffer
}
// buff转16进制
export const ab2hex = (buffer: any) => {
let hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function (bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('');
}
// 获取Mac地址
export const getMacAddress = (advertisData: any) => {
const mac = Array.prototype.map
.call(new Uint8Array(advertisData), (x) => ("00" + x.toString(16)).slice(-2))
.join(":");
return mac.toUpperCase();
}

被折叠的 条评论
为什么被折叠?



