复制文本到剪切板
/**
* 复制文本到剪切板
* @param {String} text 要复制的内容
* @param {Function} callback 回调
*/
export const copyText = (text, callback) => {
var tag = document.createElement("input");
tag.setAttribute("id", "cp_hgz_input");
tag.value = text;
document.getElementsByTagName("body")[0].appendChild(tag);
document.getElementById("cp_hgz_input").select();
document.execCommand("copy");
document.getElementById("cp_hgz_input").remove();
if (callback && typeof callback == "function") {
callback(text);
}
}
获取当前选中文本内容
// 获取选中文本内容
const getSelection = () => window.getSelection().toString()
下载
1. 下载内容(文件流形式)
/**
* H5下载内容(文件流形式)
* @param {String} content 下载内容
* @param {String} filename 文件名
*/
export const downFile = (content, filename) => {
var ele = document.createElement('a');
ele.download = filename;
ele.style.display = 'none';
var blob = new Blob([content]);
ele.href = URL.createObjectURL(blob);
document.body.appendChild(ele);
ele.click();
document.body.removeChild(ele);
};
2. 下载文件(URL形式)
/**
* 下载文件(URL形式)
* @param {String} url 下载地址
* @param {String} filename 文件名
*/
export const downFile = (url, filename) => {
let ele = document.createElement("a");
ele.download = filename;
ele.href = url;
document.body.appendChild(ele);
ele.click();
document.body.removeChild(ele);
ele.click();
}
3.下载在线文件
使用上述方法 downFile
下载文件, 如果是PDF格式的, 会直接在浏览器中打开,而非下载,因此需将文件转换为文件流形式再下载。
/**
* 下载在线文件
* @param {String} url 网络地址
* @param {String} filename 文件名
*/
export const downloadFile = (url, filename) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "blob";
xhr.onload = function () {
const blob = xhr.response;
const link = document.createElement("a");
link.href = window.URL.createObjectURL(blob);
link.download = filename; // 下载时的文件名,可自行更改
link.click();
window.URL.revokeObjectURL(link.href);
};
xhr.send();
}
图片转base64
/**
* 图片转base64
* @param {String} src 图片地址(网络图片/本地图片)
* @returns base64 图片地址
*/
export const Image2Base64 = (src) => {
return new Promise((resolve, reject) => {
var img = new Image();
img.src = src
img.crossOrigin = "anonymous";
img.onload = function() {
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, img.width, img.height);
var base64 = canvas.toDataURL("image/png");
resolve(base64)
}
})
}
// base64 转文件流
base64toFile (dataurl, filename) {
var arr = dataurl.split(',')
var mime = arr[0].match(/:(.*?);/)[1]
var bstr = atob(arr[1])
var n = bstr.length
var u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], filename, { type: mime })
}
获取地址栏参数
/**
* 获取地址栏参数
* @param {String} name 地址栏参数名称
* @param {String} url 地址栏全地址,不传自动取地址栏
*/
export const getQueryString = (name, url) => {
if (url && url.split('?').length == 2) {
url = url.split('?')[1]
} else {
url = window.location.search.substr(1)
}
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = url.match(reg);
if (r != null) return unescape(r[2]);
return null;
}
设置不同环境是否显示打印信息(console.log)
根据不同的环境,设置是否显示打印信息,一般我们生产环境考虑到内存外溢,会屏蔽 console
相关打印信息,但是开发偶尔会忘记删除,导致外溢。因此,可通过以下代码实现取消打印。
注意:需放在全局调用
/**
* 否开启日志调试,True 输出 False 不输出
*
* @param {Object}
* @param {Boolean} params.development 开发环境
* @param {Boolean} params.staging 测试环境
* @param {Boolean} params.production 生产环境
* */
export const consoleConfig = ({
development = false,
staging = false,
production = false,
}) => {
console_log = {
development,
staging,
production,
}
let nodeDev = Object.keys(console_log).find((key) => {
return process.env.NODE_ENV === key
})
var logDebug = console_log[nodeDev];
console.log = (function(oriLogFunc) {
return function() {
if (logDebug) {
oriLogFunc.apply(this, arguments);
}
}
})(console.log);
}
隐藏手机号中间4位
/**
* 隐藏手机号中间4位
* @param {String} phone 11位手机号
*/
export const replaceByPhone = (phone) => phone.replace(/^(\d{3})\d{4}(\d{4})$/, '$1****$2');
禁止浏览器双指缩放
const doubleZoomDisable = () => {
window.addEventListener(
"mousewheel",
function (event) {
if (event.ctrlKey === true || event.metaKey) {
event.preventDefault();
}
},
{ passive: false }
);
//firefox
window.addEventListener(
"DOMMouseScroll",
function (event) {
if (event.ctrlKey === true || event.metaKey) {
event.preventDefault();
}
},
{ passive: false }
);
}
范围内生成不重复的数字
/**
* 范围内生成不重复的数字,返回值中会带有arr
* @param {Number} arr 当前已有数据,根据业务需要此处可自行决定是否深度拷贝
* @param {Number} maxIndex 返回最大数字
* @param {Number} multiple 是否返回多个
*
@returns 当前生成的数字(下标形式)
*/
export const getNumNoRepeat = (exists = [], maxIndex = 10, multiple = false) => {
let times = maxIndex * 10; // 最多循环取值,超出返回 -1
let indexs = [...exists];
const getSingle = () => {
do {
var num = Math.floor(Math.random() * maxIndex);
if (-1 == indexs.indexOf(num)) { //数组中不存在
indexs.push(num);
return num;
}
times -= 1;
if (times == 0) return -1
} while (times);
}
if (!multiple) {
// 单条
return getSingle()
} else {
// 多条
if (exists.length > maxIndex) return []
for (let i = 0; i <= maxIndex - exists.length; i++) {
getSingle();
}
return indexs
}
}
例如:
// 生成5以内包含[1,5]的不重复数字
getNumNoRepeat3([1, 5], 5, true) // [1, 5, 2, 0, 4]
// 生成5以内的不重复数字
getNumNoRepeat3([], 5, true) // [2, 4, 1, 3, 0]
解决微信小程序富文本内容中字体颜色失效问题
/**
* html富文本内容 - font的color属性改为style中添加color
* @example <font color="#348aff" /> => <font style="color: #348aff" />
*/
export const fontColor2StyleColorByHtml = (str) => {
return str.replace(/\<font\s*color=(.*?)\s*>/ig, "<font style=\"color:$1\">")
}
随机生成十六进制
// 随机生成十六进制
const generateHex = () => `#${(~~(Math.random() * (1 << 24))).toString(16).padEnd(6, '0')}`
前端实现网络图片批量下载
前端实现网络图片批量转base64、写入zip、批量下载
/**
* 前端实现网络图片批量下载
* @description 该方法需要安装 jszip 依赖包
*
* @param {Array} files 需要下载的图片数组
* @param {String} files[].filePath 图片网络地址
* @param {String} files[].fileName 图片名称,不填写取 filePath
* @param {String} zipName zip 名称
* @param {String} success 成功回调
* @param {String} fail 失败回调
*
*/
export const networkImageToZip = async ({
files = [],
zipName = 'demo',
success,
fail
}) => {
let startTime = new Date().getTime();
// 加入zip文件
function addToZip(zip, base64, name) {
return new Promise((resolve, reject) => {
//过滤base64格式
let image = base64.replace(/^data:image\/(png|jpg|jpeg);base64,/, "");
let imageNames = `${name}.png`;
zip.file(imageNames, image, {
base64: true
});
resolve();
});
}
//下载zip文件到本地
function createZip(zip) {
zip
.generateAsync({
type: "blob",
})
.then((content) => {
let endTime = new Date().getTime();
console.warn(`下载用时: ${endTime - startTime}ms`);
success && success()
saveAs(content, `${zipName}.zip`);
})
.catch((err) => {
fail && fail(err)
});
}
try {
const JSZip = require("jszip")
const zip = new JSZip();
// 网络地址转base64
let base64s = await Promise.all(
files.map((item) => {
return new Promise(async (resolve, reject) => {
var xhr = new XMLHttpRequest()
xhr.open('get', item.filePath, true)
xhr.responseType = "blob";
xhr.onload = function () {
if (this.status === 200) {
let oFileReader = new FileReader();
oFileReader.onloadend = function (e) {
resolve({
base64: e.target.result,
fileName: item.fileName || item.filePath,
});
};
oFileReader.readAsDataURL(this.response);
}
}
xhr.send();
});
})
)
// base64 写入 zip 文件
base64s.map(async (it) => {
await addToZip(zip, it.base64, it.fileName);
});
createZip(zip);
} catch (err) {
fail && fail(err)
}
}
禁止用户按F12启用开发者模式
在项目上线后,用户可以通过F12查看代码接口等信息,此时调用以下方法可以阻止用户此操作,效果如下:
/**
* 禁用开发者模式(f12)
* @param {String} path 跳转路径
* @param {String} innerHTML 页面提示内容,支持html
*/
export const developingMode = (path, innerHTML) => {
(function noDebuger() {
function testDebuger() {
var d = new Date();
debugger;
if (new Date() - d > 10) {
document.body.innerHTML = `<div style="width: 100%;height: 100vh;font-size: 30px;text-align: center;font-weight: bold;">${innerHTML || '不要这样子啦~'}<a href="${path}" target="_blank" style="cursor: pointer; color:#4285f4;">点击返回</a>~</div>`;
return true
}
return false
}
function start() {
while (testDebuger()) {
testDebuger()
}
}
if (!testDebuger()) {
window.onblur = function() {
setTimeout(function() {
start()
}, 500)
}
} else {
start()
}
})();
var x = document.createElement('div');
Object.defineProperty(x, 'id', {
get: function() {
var a = "";
for (var i = 0; i < 99999999999; i++) {
a = a + i.toString()
}
}
});
window.onkeydown = window.onkeyup = window.onkeypress = function(a) {
if (a.keyCode == 123) {
document.querySelector("body div").append("TIHI!@#$%^&*()_+)()*&*^&TGYGJGYGuygT^&6746t78t78g785tgyuGGIUGOIUB&^Y(*^&^$$&*G*GUIGUOUIYUIT&*%$^%#^%ER^%RF&FGIY*G*&^T*(G*O")
}
}
}
时间格式化
/**
* 时间格式化
* @param {*} time
*/
export function formatDate(time) {
if (!time) return "";
const date = new Date(time);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
padStart
方法用来确定字符串长度, 不足用0补全
实现文字打字输出效果
/**
* 实现文字打字输出效果
* @param {number} textElement
* @param {string} delay
*/
export const typewriterEffect = (textElement, delay = 100) => {
const text = textElement.textContent;
textElement.textContent = "";
let i = 0;
const timer = setInterval(() => {
textElement.textContent += text[i];
i++;
if (i === text.length) {
clearInterval(timer);
}
}, delay);
}
使用
// <div id="text">打字效果打字效果打字效果打字效果打字效果打字效果打字效果</div>
typewriterEffect(document.getElementById("text"), 100);
JS八大类型判断
/**
* 数据类型判断
* @param {*} _
* @returns {String} 输出类型: [Number|String|Boolean|Undefined|Null|Object|Array|Function]
*/
const typeOf = (_) => Object.prototype.toString.call(_).slice(8, -1);
测试结果如下:
typeOf(1); // Number
typeOf("1"); // String
typeOf(true); // Boolean
typeOf(null); // Null
typeOf(undefined); // Undefined
typeOf(Symbol(1)); // Symbol
typeOf({}); // Object
typeOf([]); // Array
typeOf(function () { }); // Function
typeOf(new Date()); // Date
typeOf(new RegExp()); // RegExp