关于前端开发中常用的工具函数的记录
/**
* 深度复制
*/
isClone(obj) {
if (null == obj || 'object' !== typeof obj) {
return obj;
}
if (obj instanceof Date) {
const copy = new Date();
copy.setTime(obj.getTime());
return copy;
}
if (obj instanceof Array) {
const copy = [];
for (let i = 0, len = obj.length; i < len; ++i) {
copy[i] = this.isClone(obj[i]);
}
return copy;
}
if (obj instanceof Object) {
const copy = {};
for (const attr in obj) {
if (obj.hasOwnProperty(attr)) {
copy[attr] = this.isClone(obj[attr]);
}
}
return copy;
}
throw new Error("Unable to copy obj! Its type isn't supported.");
}
/**
* 删除对象中指定属性
* @param obj [受检查对象]
* @param keys [指定属性]
* 使用方法:isObjectDelKay(obj, "id")
*/
isObjectDelKay(obj, keys) {
if (!Array.isArray(obj)) {
for (const i in obj) {
if (obj.hasOwnProperty(i)) {
if (i === keys) {
delete obj[i];
}
if (Array.isArray(obj[i])) {
this.isObjectDelKay(obj[i], keys);
}
}
}
} else {
for (const i in obj) {
if (obj.hasOwnProperty(i)) {
this.isObjectDelKay(obj[i], keys);
}
}
}
return obj;
}
/**
* Guid 生成指定长度的数字
* @param size 长度
*/
isGuid(size: number): string {
let guid = '';
for (let i = 1; i <= size; i++) {
const n = Math.floor(Math.random() * 16.0).toString(16);
guid += n;
}
return guid;
}
/**
* bold转文件带下载
* @param _file_data || blob 文件流
* @param _file_name 下载文件名称指定
*/
isDownload(blob: Blob, fileName?: string) {
// const blob = new Blob([_file_data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
const isBlob = blob instanceof Blob;
if (!isBlob) {
return;
}
const objectUrl = URL.createObjectURL(blob);
const a = document.createElement('a');
document.body.appendChild(a);
a.setAttribute('style', 'display:none');
a.setAttribute('href', objectUrl);
a.setAttribute('download', fileName || `${Date.now()}.jpg`);
a.click();
document.body.removeChild(a);
// 释放URL地址
URL.revokeObjectURL(objectUrl);
}
convertUrlToBase64(url: string): Promise {
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = 'Anonymous';
console.log(img);
img.src = url;
img.onload = () => {
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, img.width, img.height);
const ext = img.src.substring(img.src.lastIndexOf('.') + 1).toLowerCase();
const type = `image/${ext}`;
const dataUrl = canvas.toDataURL(type);
const base64: Base64 = {
dataUrl,
type,
ext
};
resolve(base64);
};
img.onerror = err => reject(err);
});
}
/**
* base64 转 blob
* @param base64 { Base64 }
*
* return Blob
*/
convertBase64UrlToBlob(base64: Base64): Blob {
const parts = base64.dataUrl.split(';base64,');
const contentType = parts[0].split(':')[1];
const raw = window.atob(parts[1]);
const rawLength = raw.length;
const uInt8Array = new Uint8Array(rawLength);
for (let i = 0; i < rawLength; i++) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], { type: contentType });
}
/**
* 实现选择某个dom节点
* @param targetNode
*/
getSelect(targetNode) {
if (window.getSelection) {
// chrome等主流浏览器
const selection = window.getSelection();
const range = document.createRange();
range.selectNode(targetNode);
selection.removeAllRanges();
selection.addRange(range);
} else if (document.body['createTextRange']) {
// ie
const range = document.body['createTextRange']();
range.moveToElementText(targetNode);
range.select();
}
}
/**
* create a image element
* @param options
*
* return imgEle
*/
createImage(options: any = {}) {
const img = Image ? new Image() : document.createElement('img');
if (options['src']) {
img.src = options['src'];
}
return img;
}
/**
* 判断样式是否存在
* @param elem element
* @param cls 样式名称
*/
hasClass(elem, cls) {
cls = cls || '';
// 当cls没有参数时,返回false
if (cls.replace(/\s/g, '').length === 0) {
return false;
}
return new RegExp(' ' + cls + ' ').test(' ' + elem.className + ' ');
}
/**
* 添加样式名
* @param ele element
* @param cls 样式名称
*/
addClass(ele, cls) {
if (!this.hasClass(ele, cls)) {
ele.className = ele.className === '' ? cls : ele.className + ' ' + cls;
}
}
/**
* 删除样式名
* @param richtxt 对象
* @param cls 样式名
*/
delClass(richtxt: any, cls: string) {
let obj_class = ' ' + richtxt.className + ' '; // 获取 class 内容, 并在首尾各加一个空格. ex) 'abc bcd' -> ' abc bcd '
obj_class = obj_class.replace(/(\s+)/gi, ' '); // 将多余的空字符替换成一个空格. ex) ' abc bcd ' -> ' abc bcd '
let removed = obj_class.replace(' ' + cls + ' ', ' '); // 在原来的 class 替换掉首尾加了空格的 class. ex) ' abc bcd ' -> 'bcd '
removed = removed.replace(/(^\s+)|(\s+$)/g, ''); // 去掉首尾空格. ex) 'bcd ' -> 'bcd'
richtxt.className = removed; // 替换原来的 class.
}
/**
* 随机生成颜色
*/
getRandomColor() {
// tslint:disable-next-line:no-bitwise
return '#' + ('00000' + ((Math.random() * 0x1000000) << 0).toString(16)).slice(-6);
}
/**
* @desc 判断初始值是否为所需类型,不是则返回备用值(一般为该类型的空值)
* @param original 原始值
* @param backup 备用值
*/
factory(original: any, backup: any = ''): any {
const srcType = this.typeOf(original);
const desType = this.typeOf(backup);
if (srcType === desType) {
return original;
} else {
return backup;
}
}
/**
* @desc 取值函数
*
*/
calc(obj: any, path: string | Array, type: any): any {
path = Array.isArray(path)
? path
: path
.replace(/\[/g, '.')
.replace(/\]/g, '')
.split('.');
const result = path.reduce((o, k) => (o || {})[k], obj);
if (result || result === 0) {
// return path.reduce((o, k) => (o || {})[k], obj);
return result;
} else {
return this.factory(result, type);
}
}
/**@desc 把多个树结构打平成数组, 不包括父节点 */
treeFlat(obj: NzTreeNode[]): NzTreeNode[] {
return obj.reduce((prevArr, cnode) => {
if (cnode.children && cnode.children.length > 0) {
return [...prevArr, ...this.treeFlat(cnode.children)];
} else {
return [...prevArr, cnode];
}
}, []);
}
/**
*生成树形结构数组
*/
createTreeData(original, childIdProp, parentIdProp) {
let index = 0;
const tree = [];
let item = original[0];
const treeObj = {};
const len = original.length;
let id: any, parent: any, parentId: number;
// 生成treeObj字典
original.forEach(row => (treeObj[row[childIdProp]] = row));
while (index < len) {
item = original[index++];
id = item[childIdProp];
parentId = item[parentIdProp];
if (parentId || parentId === 0) {
parent = treeObj[parentId];
if (parent) {
parent.children ? parent.children.push(item) : (parent.children = [item]);
}
} else {
tree.push(item);
}
}
console.log(tree);
return tree;
}
/**
* 判断选中的经纬度是否在dubai范围内
*/
determineScope(data) {
const minLatLon = [53.0644416809082, 22.8470668792725];
const maxLatLon = [56.3852233886719, 26.0664596557617];
if (data[0] > minLatLon[0] && data[0] < maxLatLon[0] && data[1] > minLatLon[1] && data[1] < maxLatLon[1]) {
return true;
} else {
return false;
}
}
/**
* 判断结束时间不能小于等于开始时间
*/
judgeST_ET(fm) {
let startT = fm.value.startTime ? fm.value.startTime.getTime() : null;
let endT = fm.value.endTime ? fm.value.endTime.getTime() : null;
if (!startT && !endT) {
return;
}
const timeOut = setTimeout(() => {
if (startT && startT < new Date().getTime()) {
startT = new Date().getTime() + 60 * 60 * 1000;
fm.controls.startTime.setValue(new Date(startT));
}
if (endT && endT < new Date().getTime()) {
endT = new Date().getTime() + 2 * 60 * 60 * 1000;
fm.controls.endTime.setValue(new Date(endT));
}
if (startT && endT) {
if (startT > endT) {
fm.controls.endTime.setValue(null);
}
}
}, 1000);
clearTimeout(timeOut);
}
parseFromJSON(json: string = null, type: 'Object' | 'Array') {
const map = {
Object: {},
Array: []
};
let source;
// get error;
try {
source = JSON.parse(json);
} catch (e) {
source = map[type];
}
// get null;
if (!source) {
source = map[type];
}
// get no object or array
if (this.typeOf(source) !== type) {
source = map[type];
}
return source;
}