前言
前端的工具库,常用的也都比较多,一些数据转换、格式化、存储等,也都比较杂,我们试着进行一个大的归类
- 文字复杂、文件下载
- 全屏处理公用方法
- 图片下载以及转换 base64/blob等
copy.js
export default function copy(text) {
const input = document.createElement("input");
input.type = "text";
input.value = text;
document.body.appendChild(input);
input.select();
document.execCommand("copy");
input.remove()
}
这个思路是在全局的根节点下,创建一个input标签,然后把赋值选中,使用execCommand执行复制动作
download.js
创建 A 标签下载
/**
* 创建A标签下载
* @param {string} url: 下载地址
* @param {string} title: 下载标题
* @param {string} target: 窗口位置(默认新开窗口)
*/
export default function download({ url, title = '', target = '_blank' }) {
let tagA = document.createElement('a');
tagA.setAttribute('href', url);
tagA.setAttribute('download', title);
tagA.setAttribute('target', target);
document.body.appendChild(tagA);
tagA.click();
document.body.removeChild(tagA);
}
临时创建一个a标签,设置相关下载相关属性,然后执行点击动作
业务应用
//使用示例
import { download } from '@basic-utils';
download({ url: path, title });
fullScreenHelper 全屏
浏览器窗口全屏方法
业务应用
//使用示例
import { fullScreenHelper } from '@basic-utils';
//判断是否全屏
const fullScreenEle = fullScreenHelper.isFullscreen();
if (fullScreenEle) {
//退出全屏
fullScreenHelper.exitFullscreen();
} else {
//进入全屏
fullScreenHelper.fullscreen('dom');
}
源代码:
function fullscreen(element) {
if (element.requestFullScreen) {
element.requestFullScreen();
} else if (element.webkitRequestFullScreen) {
element.webkitRequestFullScreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen();
}
}
/**
* exitFullscreen 退出全屏
* @param {Objct} element 选择器
*/
function exitFullscreen() {
if (!isFullscreen()) {
return;
}
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
}
/**
* 判读是否支持全屏
*/
function fullscreenEnabled() {
return document.fullscreenEnabled || document.mozFullScreenEnabled || document.webkitFullscreenEnabled || document.msFullscreenEnabled;
}
/**
* [isFullscreen 判断浏览器是否全屏]
* @return [全屏则返回当前调用全屏的元素,不全屏返回false]
*/
function isFullscreen() {
return document.fullscreenElement || document.msFullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || false;
}
// 添加 / 移除 全屏事件监听
function fullScreenListener(type, fullscreenchange) {
const fullScreenEvents = ['fullscreenchange', 'mozfullscreenchange', 'webkitfullscreenchange', 'msfullscreenchange'];
fullScreenEvents.map((v) => document[type](v, fullscreenchange));
}
export default {
fullScreenListener,
isFullscreen,
fullscreenEnabled,
exitFullscreen,
fullscreen,
};
imageMethods
图片转换方法
业务应用
//使用示例
import { imageMethods } from '@basic-utils';
//图片base64转换为blob
const oldFile = imageMethods.base64ToBlob(base64Url);
//转base64下载网络图片
imageMethods.downloadLocalImage(imgUrl, title);
//图片地址转base64
imageMethods.urlToBase64({ imgUrl, imgQuality: 0.8 }, (base64Url, err) => {});
API
下载网络图片 downloadLocalImage
图片地址转base64 urlToBase64
dom绘图获取base64Url drawImage
图片base64转换为blob base64ToBlob
源代码
import tagAToDownload from './download';
/**
* 下载网络图片
* @param imgUrl: 下载地址
* @param title: 下载标题
*/
function downloadLocalImage(imgUrl, title) {
urlToBase64({ imgUrl, imgQuality: 0.8 }, (base64Url, err) => {
if (err) return console.error(err);
let path = URL.createObjectURL(base64ToBlob(base64Url));
tagAToDownload({
url: path,
title,
});
setTimeout(() => {
URL.revokeObjectURL(path);
}, 10000);
});
}
/**
* 图片地址转base64
*/
function urlToBase64({ imgUrl, imgQuality = 1, width, height }, callback) {
let img = document.createElement('img');
// crossOrigin属性必须在src之前,否则会报错!!
img.setAttribute('crossOrigin', 'anonymous');
img.src = imgUrl;
img.onload = () => {
width = width ? width : img.width;
height = height ? height : img.height;
const base64Url = drawImage({
target: img,
width,
height,
imgQuality,
});
return callback && callback(base64Url, null);
};
img.onerror = (err) => {
return callback && callback(null, err);
};
}
/**
* dom绘图获取base64Url
* @param {element} target: 绘图目标: video、img、canvas
* @param {Number} width: 图片宽度
* @param {Number} height: 图片高度
* @param {string} imgType: 图片类型
* @param {Number} imgQuality: 图片质量 0-1
*/
function drawImage({ target, width, height, imgType = 'image/jpeg', imgQuality = 1 }) {
let canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
canvas.getContext('2d').drawImage(target, 0, 0);
const base64Url = canvas.toDataURL(imgType, imgQuality);
return base64Url;
}
/**
* 图片base64转换为blob
* @param {string} base64Url
*/
function base64ToBlob(base64Url) {
// 去掉url的头,并转换为byte
var bytes = window.atob(base64Url.split(',')[1]);
// 处理异常,将ascii码小于0的转换为大于0
var ab = new ArrayBuffer(bytes.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
return new Blob([ab], { type: 'image/png' });
}
export default {
downloadLocalImage,
urlToBase64,
drawImage,
base64ToBlob,
};
UUID
通用唯一标识
业务应用
//使用示例
import { uuid } from '@basic-utils';;
const id = uuid();
源代码
/**
* 生成UUID
*/
export default function uuid() {
let s = [];
let hexDigits = '0123456789abcdef';
for (let i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[14] = '4';
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
s[8] = s[13] = s[18] = s[23] = '-';
let uuidStr = s.join('');
return uuidStr;
}
queryHelper
URL参数处理方法集合
API:
comparisonPahtname
判断2个path是否相等
queryFormat
对URL后的参数字符串转换成JSON
objectToQuery
对象转化为&连接符拼接
源代码:
/**
* 处理location.search的方法,将字符串转换成json
* @param {string} search
*/
export function queryFormat(search = '') {
let params = {};
if (search === '') {
return params;
}
if (typeof search === 'string') {
search = search.indexOf('?') < 0 ? search : search.substr(search.indexOf('?') + 1);
let a = search.split('&');
let b = a.map((v) => v.split('='));
b.map((v) => (params[v[0]] = v[1]));
}
return params;
}
/**
* @desc 对象转化为&连接符拼接
*/
export function objectToQuery(params) {
let url = '';
for (var i in params) {
if (params[i]) {
url += `${i}=${params[i]}&`;
}
}
return url.substr(0, url.length - 1);
}
function comparisonPahtname(pathname1, pathname2) {
if (!pathname1 || !pathname2) {
return false;
}
if (pathname1 === pathname2) {
return true;
}
const arr1 = pathname1.split('/');
const arr2 = pathname2.split('/');
if (arr1.length !== arr2.length) {
return false;
}
return arr1.every((v, i) => {
if (v === arr2[i]) {
return true;
}
if (arr2[i].includes(':')) {
return true;
}
return false;
});
}
export default {
comparisonPahtname,
queryFormat,
objectToQuery,
};
核心解读
comparisonPahtname,对2个path进行了多重判断
1、字符串
2、分割后数组长度判断
3、数组内每项进行判断,如果目标项中包含 : 就视为正常
queryFormat
参数后缀获取使用 location.search,对其进行了解析,?号和&进行查找和分割,遍历组装到对象返回。
isEqual
数据深比较
业务应用
//使用示例
import { isEqual } from '@basic-utils';
const isBool = !isEqual(obj, obj2);
源代码
import equal from 'fast-deep-equal';
export default function isEqual(objValue, othValue) {
return equal(objValue, othValue);
}
核心解读
fast-deep-equal
深度的比较插件,性能比lodash高好几倍
性能基准:
fast-deep-equal x 261,950 ops/sec ±0.52% (89 runs sampled)
fast-deep-equal/es6 x 212,991 ops/sec ±0.34% (92 runs sampled)
fast-equals x 230,957 ops/sec ±0.83% (85 runs sampled)
nano-equal x 187,995 ops/sec ±0.53% (88 runs sampled)
shallow-equal-fuzzy x 138,302 ops/sec ±0.49% (90 runs sampled)
underscore.isEqual x 74,423 ops/sec ±0.38% (89 runs sampled)
lodash.isEqual x 36,637 ops/sec ±0.72% (90 runs sampled)
deep-equal x 2,310 ops/sec ±0.37% (90 runs sampled)
deep-eql x 35,312 ops/sec ±0.67% (91 runs sampled)
ramda.equals x 12,054 ops/sec ±0.40% (91 runs sampled)
util.isDeepStrictEqual x 46,440 ops/sec ±0.43% (90 runs sampled)
assert.deepStrictEqual x 456 ops/sec ±0.71% (88 runs sampled)
The fastest is fast-deep-equal
老铁们,系列设计持续更新中:
浅谈应用设计-basic-utils工具库
浅谈前端工具库设计--数据类
浅谈前端工具库设计--存储类
浅谈前端工具库设计--通信类