1、校验数据类型
export const typeOf = function(obj) {
return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase()
}
示例:
typeOf('树哥') // string
typeOf([]) // array
typeOf(new Date()) // date
typeOf(null) // null
typeOf(true) // boolean
typeOf(() => { }) // function
2、防抖
export const debounce = (() => {
let timer = null
return (callback, wait = 800) => {
timer&&clearTimeout(timer)
timer = setTimeout(callback, wait)
}
})()
示例:
如 vue 中使用
methods: {
loadList() {
debounce(() => {
console.log('加载数据')
}, 500)
}
}
3、节流
export const throttle = (() => {
let last = 0
return (callback, wait = 800) => {
let now = +new Date()
if (now - last > wait) {
callback()
last = now
}
}
})()
export const throttle = (fn, delay) => {
let curTime = Date.now();
return function() {
let context = this,
args = arguments,
nowTime = Date.now();
if (nowTime - curTime >= delay) {
curTime = Date.now();
return fn.apply(context, args);
}
};
}
4、手机号脱敏
export const hideMobile = (mobile) => {
return mobile.replace(/^(\d{3})\d{4}(\d{4})$/, "$1****$2")
}
5、开启全屏
export const launchFullscreen = (element) => {
if (element.requestFullscreen) {
element.requestFullscreen()
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen()
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen()
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullScreen()
}
}
function fullScreen() {
const el = document.documentElement
const rfs =
el.requestFullScreen ||
el.webkitRequestFullScreen ||
el.mozRequestFullScreen ||
el.msRequestFullscreen
if(typeof rfs != "undefined" && rfs) {
rfs.call(el)
}
}
fullScreen()
6、关闭全屏
export const exitFullscreen = () => {
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.msExitFullscreen) {
document.msExitFullscreen()
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen()
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen()
}
}
function exitScreen() {
if (document.exitFullscreen) {
document.exitFullscreen()
}
else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen()
}
else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen()
}
else if (document.msExitFullscreen) {
document.msExitFullscreen()
}
if(typeof cfs != "undefined" && cfs) {
cfs.call(el)
}
}
exitScreen()
7、大小写转换
参数:
-
str 待转换的字符串
-
type 1-全大写 2-全小写 3-首字母大写
export const turnCase = (str, type) => {
switch (type) {
case 1:
return str.toUpperCase()
case 2:
return str.toLowerCase()
case 3:
//return str[0].toUpperCase() + str.substr(1).toLowerCase() // substr 已不推荐使用
return str[0].toUpperCase() + str.substring(1).toLowerCase()
default:
return str
}
}
示例:
turnCase('vue', 1) // VUE
turnCase('REACT', 2) // react
turnCase('vue', 3) // Vue
8、解析URL参数
export const getSearchParams = () => {
const searchPar = new URLSearchParams(window.location.search)
const paramsObj = {}
for (const [key, value] of searchPar.entries()) {
paramsObj[key] = value
}
return paramsObj
}
示例:
// 假设目前位于 https://****com/index?id=154513&age=18;
getSearchParams(); // {id: "154513", age: "18"}
9、判断手机是Andoird还是IOS
/**
* 1: ios
* 2: android
* 3: 其它
*/
export const getOSType=() => {
let u = navigator.userAgent, app = navigator.appVersion;
let isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1;
let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
if (isIOS) {
return 1;
}
if (isAndroid) {
return 2;
}
return 3;
}
10、数组对象根据字段去重
参数:
-
arr 要去重的数组
-
key 根据去重的字段名
export const uniqueArrayObject = (arr = [], key = 'id') => {
if (arr.length === 0) return
let list = []
const map = {}
arr.forEach((item) => {
if (!map[item[key]]) {
map[item[key]] = item
}
})
list = Object.values(map)
return list
}
示例:
const responseList = [
{ id: 1, name: '树哥' },
{ id: 2, name: '黄老爷' },
{ id: 3, name: '张麻子' },
{ id: 1, name: '黄老爷' },
{ id: 2, name: '张麻子' },
{ id: 3, name: '树哥' },
{ id: 1, name: '树哥' },
{ id: 2, name: '黄老爷' },
{ id: 3, name: '张麻子' },
]
uniqueArrayObject(responseList, 'id')
// [{ id: 1, name: '树哥' },{ id: 2, name: '黄老爷' },{ id: 3, name: '张麻子' }]
11、滚动到页面顶部
export const scrollToTop = () => {
const height = document.documentElement.scrollTop || document.body.scrollTop;
if (height > 0) {
window.requestAnimationFrame(scrollToTop);
window.scrollTo(0, height - height / 8);
}
}
11、滚动到页面底部
export const scrollToBottom = () => {
window.scrollTo(0, document.documentElement.clientHeight);
}
12、滚动到元素位置
export const smoothScroll = element =>{
document.querySelector(element).scrollIntoView({
behavior: 'smooth'
});
};
示例:
smoothScroll('#target'); // 平滑滚动到 ID 为 target 的元素
13、uuid
export const uuid = () => {
const temp_url = URL.createObjectURL(new Blob())
const uuid = temp_url.toString()
URL.revokeObjectURL(temp_url) //释放这个url
return uuid.substring(uuid.lastIndexOf('/') + 1)
}
示例:
uuid() // a640be34-689f-4b98-be77-e3972f9bffdd
14、金额格式化
参数:
-
{number} number:要格式化的数字
-
{number} decimals:保留几位小数
-
{string} dec_point:小数点符号
-
{string} thousands_sep:千分位符号
export const moneyFormat = (number, decimals, dec_point, thousands_sep) => {
number = (number + '').replace(/[^0-9+-Ee.]/g, '')
const n = !isFinite(+number) ? 0 : +number
const prec = !isFinite(+decimals) ? 2 : Math.abs(decimals)
const sep = typeof thousands_sep === 'undefined' ? ',' : thousands_sep
const dec = typeof dec_point === 'undefined' ? '.' : dec_point
let s = ''
const toFixedFix = function(n, prec) {
const k = Math.pow(10, prec)
return '' + Math.ceil(n * k) / k
}
s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.')
const re = /(-?\d+)(\d{3})/
while (re.test(s[0])) {
s[0] = s[0].replace(re, '$1' + sep + '$2')
}
if ((s[1] || '').length < prec) {
s[1] = s[1] || ''
s[1] += new Array(prec - s[1].length + 1).join('0')
}
return s.join(dec)
}
示例:
moneyFormat(10000000) // 10,000,000.00
moneyFormat(10000000, 3, '.', '-') // 10-000-000.000
15、存储操作
class MyCache {
constructor(isLocal = true) {
this.storage = isLocal ? localStorage : sessionStorage
}
setItem(key, value) {
if (typeof (value) === 'object') value = JSON.stringify(value)
this.storage.setItem(key, value)
}
getItem(key) {
try {
return JSON.parse(this.storage.getItem(key))
} catch (err) {
return this.storage.getItem(key)
}
}
removeItem(key) {
this.storage.removeItem(key)
}
clear() {
this.storage.clear()
}
key(index) {
return this.storage.key(index)
}
length() {
return this.storage.length
}
}
const localCache = new MyCache()
const sessionCache = new MyCache(false)
export { localCache, sessionCache }
示例:
localCache.getItem('user')
sessionCache.setItem('name','树哥')
sessionCache.getItem('token')
localCache.clear()
16、下载文件
参数:
-
api 接口
-
params 请求参数
-
fileName 文件名
const downloadFile = (api, params, fileName, type = 'get') => {
axios({
method: type,
url: api,
responseType: 'blob',
params: params
}).then((res) => {
let str = res.headers['content-disposition']
if (!res || !str) {
return
}
let suffix = ''
// 截取文件名和文件类型
if (str.lastIndexOf('.')) {
fileName ? '' : fileName = decodeURI(str.substring(str.indexOf('=') + 1, str.lastIndexOf('.')))
suffix = str.substring(str.lastIndexOf('.'), str.length)
}
// 如果支持微软的文件下载方式(ie10+浏览器)
if (window.navigator.msSaveBlob) {
try {
const blobObject = new Blob([res.data]);
window.navigator.msSaveBlob(blobObject, fileName + suffix);
} catch (e) {
console.log(e);
}
} else {
// 其他浏览器
let url = window.URL.createObjectURL(res.data)
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.target = '_blank';
link.setAttribute('download', fileName + suffix)
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
window.URL.revokeObjectURL(link.href);
}
}).catch((err) => {
console.log(err.message);
})
}`
使用:
downloadFile('/api/download', {id}, '文件名')
17、时间操作
1、日期转换
const formatYmd = (date) => date.toISOString().slice(0, 10);
formatYmd(new Date())
2、 将秒数转换为 hh:mm:ss 格式
const formatSeconds = (s) => new Date(s * 1000).toISOString().substr(11, 8)
formatSeconds(200) // 00:03:20
3、 获取某年某月的第一天
const getLastDate = (d = new Date()) => new Date(d.getFullYear(), d.getMonth() + 1, 0);
getLastDate(new Date('2023-03-04')) // Fri Mar 31 2023 00:00:00 GMT+0800 (中国标准时间)
4、获取某年月份天数
const getDaysNum = (year, month) => new Date(year, month, 0).getDate()
const day = getDaysNum(2024, 2) // 29
18、深拷贝
export const clone = parent => {
// 判断类型
const isType = (obj, type) => {
if (typeof obj !== "object") return false;
const typeString = Object.prototype.toString.call(obj);
let flag;
switch (type) {
case "Array":
flag = typeString === "[object Array]";
break;
case "Date":
flag = typeString === "[object Date]";
break;
case "RegExp":
flag = typeString === "[object RegExp]";
break;
default:
flag = false;
}
return flag;
};
// 处理正则
const getRegExp = re => {
var flags = "";
if (re.global) flags += "g";
if (re.ignoreCase) flags += "i";
if (re.multiline) flags += "m";
return flags;
};
// 维护两个储存循环引用的数组
const parents = [];
const children = [];
const _clone = parent => {
if (parent === null) return null;
if (typeof parent !== "object") return parent;
let child, proto;
if (isType(parent, "Array")) {
// 对数组做特殊处理
child = [];
} else if (isType(parent, "RegExp")) {
// 对正则对象做特殊处理
child = new RegExp(parent.source, getRegExp(parent));
if (parent.lastIndex) child.lastIndex = parent.lastIndex;
} else if (isType(parent, "Date")) {
// 对Date对象做特殊处理
child = new Date(parent.getTime());
} else {
// 处理对象原型
proto = Object.getPrototypeOf(parent);
// 利用Object.create切断原型链
child = Object.create(proto);
}
// 处理循环引用
const index = parents.indexOf(parent);
if (index != -1) {
// 如果父数组存在本对象,说明之前已经被引用过,直接返回此对象
return children[index];
}
parents.push(parent);
children.push(child);
for (let i in parent) {
// 递归
child[i] = _clone(parent[i]);
}
return child;
};
return _clone(parent);
};
此方法存在一定局限性:一些特殊情况没有处理: 例如Buffer对象、Promise、Set、Map。
如果确实想要完备的深拷贝,推荐使用 lodash 中的 cloneDeep 方法。
19、模糊搜索
参数:
-
list 原数组
-
keyWord 查询的关键词
-
attribute 数组需要检索属性
export const fuzzyQuery = (list, keyWord, attribute = 'name') => {
const reg = new RegExp(keyWord)
const arr = []
for (let i = 0; i < list.length; i++) {
if (reg.test(list[i][attribute])) {
arr.push(list[i])
}
}
return arr
}
示例:
const list = [
{ id: 1, name: '树哥' },
{ id: 2, name: '黄老爷' },
{ id: 3, name: '张麻子' },
{ id: 4, name: '汤师爷' },
{ id: 5, name: '胡万' },
{ id: 6, name: '花姐' },
{ id: 7, name: '小梅' }
]
fuzzyQuery(list, '树', 'name') // [{id: 1, name: '树哥'}]
20、遍历树节点
export const foreachTree = (data, callback, childrenName = 'children') => {
for (let i = 0; i < data.length; i++) {
callback(data[i])
if (data[i][childrenName] && data[i][childrenName].length > 0) {
foreachTree(data[i][childrenName], callback, childrenName)
}
}
}
示例:
假设我们要从树状结构数据中查找 id 为 9 的节点
const treeData = [{
id: 1,
label: '一级 1',
children: [{
id: 4,
label: '二级 1-1',
children: [{
id: 9,
label: '三级 1-1-1'
}, {
id: 10,
label: '三级 1-1-2'
}]
}]
}, {
id: 2,
label: '一级 2',
children: [{
id: 5,
label: '二级 2-1'
}, {
id: 6,
label: '二级 2-2'
}]
}, {
id: 3,
label: '一级 3',
children: [{
id: 7,
label: '二级 3-1'
}, {
id: 8,
label: '二级 3-2'
}]
}],
let result
foreachTree(data, (item) => {
if (item.id === 9) {
result = item
}
})
console.log('result', result) // {id: 9,label: "三级 1-1-1"}
21、生成指定范围随机数
export const randomNum = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
22、数字千分位分隔
export const format = (n) => {
let num = n.toString();
let len = num.length;
if (len <= 3) {
return num;
} else {
let temp = '';
let remainder = len % 3;
if (remainder > 0) { // 不是3的整数倍
return num.slice(0, remainder) + ',' + num.slice(remainder, len).match(/\d{3}/g).join(',') + temp;
} else { // 3的整数倍
return num.slice(0, len).match(/\d{3}/g).join(',') + temp;
}
}
}
23、数组扁平化
export const flatten = (arr) => {
let result = [];
for(let i = 0; i < arr.length; i++) {
if(Array.isArray(arr[i])) {
result = result.concat(flatten(arr[i]));
} else {
result.push(arr[i]);
}
}
return result;
}
24、数组中获取随机数
export const sample = arr => arr[Math.floor(Math.random() * arr.length)];
25、生成随机字符串
export const randomString = (len) => {
let chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz123456789';
let strLen = chars.length;
let randomStr = '';
for (let i = 0; i < len; i++) {
randomStr += chars.charAt(Math.floor(Math.random() * strLen));
}
return randomStr;
};
26、字符串首字母大写
export const fistLetterUpper = (str) => {
return str.charAt(0).toUpperCase() + str.slice(1);
};
27、手机号中间四位变成*
export const telFormat = (tel) => {
tel = String(tel);
return tel.substr(0,3) + "****" + tel.substr(7);
};
28、驼峰命名转换成短横线命名
export const getKebabCase = (str) => {
return str.replace(/[A-Z]/g, (item) => '-' + item.toLowerCase())
}
29、短横线命名转换成驼峰命名
export const getCamelCase = (str) => {
return str.replace( /-([a-z])/g, (i, item) => item.toUpperCase())
}
30、数字转化为大写金额
export const digitUppercase = (n) => {
const fraction = ['角', '分'];
const digit = [
'零', '壹', '贰', '叁', '肆',
'伍', '陆', '柒', '捌', '玖'
];
const unit = [
['元', '万', '亿'],
['', '拾', '佰', '仟']
];
n = Math.abs(n);
let s = '';
for (let i = 0; i < fraction.length; i++) {
s += (digit[Math.floor(n * 10 * Math.pow(10, i)) % 10] + fraction[i]).replace(/零./, '');
}
s = s || '整';
n = Math.floor(n);
for (let i = 0; i < unit[0].length && n > 0; i++) {
let p = '';
for (let j = 0; j < unit[1].length && n > 0; j++) {
p = digit[n % 10] + unit[1][j] + p;
n = Math.floor(n / 10);
}
s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s;
}
return s.replace(/(零.)*零元/, '元')
.replace(/(零.)+/g, '零')
.replace(/^整$/, '零元整');
};
31、数字转化为中文数字
export const intToChinese = (value) => {
const str = String(value);
const len = str.length-1;
const idxs = ['','十','百','千','万','十','百','千','亿','十','百','千','万','十','百','千','亿'];
const num = ['零','一','二','三','四','五','六','七','八','九'];
return str.replace(/([1-9]|0+)/g, ( $, $1, idx, full) => {
let pos = 0;
if($1[0] !== '0'){
pos = len-idx;
if(idx == 0 && $1[0] == 1 && idxs[len-idx] == '十'){
return idxs[len-idx];
}
return num[$1[0]] + idxs[len-idx];
} else {
let left = len - idx;
let right = len - idx + $1.length;
if(Math.floor(right / 4) - Math.floor(left / 4) > 0){
pos = left - left % 4;
}
if( pos ){
return idxs[pos] + num[$1[0]];
} else if( idx + $1.length >= len ){
return '';
}else {
return num[$1[0]]
}
}
});
}
32、获取URL参数列表
export const GetRequest = () => {
let url = location.search;
const paramsStr = /.+\?(.+)$/.exec(url)[1]; // 将 ? 后面的字符串取出来
const paramsArr = paramsStr.split('&'); // 将字符串以 & 分割后存到数组中
let paramsObj = {};
// 将 params 存到对象中
paramsArr.forEach(param => {
if (/=/.test(param)) { // 处理有 value 的参数
let [key, val] = param.split('='); // 分割 key 和 value
val = decodeURIComponent(val); // 解码
val = /^\d+$/.test(val) ? parseFloat(val) : val; // 判断是否转为数字
if (paramsObj.hasOwnProperty(key)) { // 如果对象有 key,则添加一个值
paramsObj[key] = [].concat(paramsObj[key], val);
} else { // 如果对象没有这个 key,创建 key 并设置值
paramsObj[key] = val;
}
} else { // 处理没有 value 的参数
paramsObj[param] = true;
}
})
return paramsObj;
};
33、键值对拼接成URL参数
export const params2Url = (obj) => {
let params = []
for (let key in obj) {
params.push(`${key}=${obj[key]}`);
}
return encodeURIComponent(params.join('&'))
}
34、修改URL中的参数
export const replaceParamVal => (paramName, replaceWith) {
const oUrl = location.href.toString();
const re = eval('/('+ paramName+'=)([^&]*)/gi');
location.href = oUrl.replace(re,paramName+'='+replaceWith);
return location.href;
}
35、删除URL中指定参数
export const funcUrlDel = (name) => {
const baseUrl = location.origin + location.pathname + "?";
const query = location.search.substr(1);
if (query.indexOf(name) > -1) {
const obj = {};
const arr = query.split("&");
for (let i = 0; i < arr.length; i++) {
arr[i] = arr[i].split("=");
obj[arr[i][0]] = arr[i][1];
}
delete obj[name];
return baseUrl + JSON.stringify(obj).replace(/[\"\{\}]/g,"").replace(/\:/g,"=").replace(/\,/g,"&");
}
}
36、判断是移动还是PC设备
export const isMobile = () => {
if ((navigator.userAgent.match(/(iPhone|iPod|Android|ios|iOS|iPad|Backerry|WebOS|Symbian|Windows Phone|Phone)/i))) {
return 'mobile';
}
return 'desktop';
}
37、判断是否是苹果还是安卓移动设备
export const isAppleMobileDevice = () => {
let reg = /iphone|ipod|ipad|Macintosh/i;
return reg.test(navigator.userAgent.toLowerCase());
}
38、判断是否是安卓移动设备
export const isAndroidMobileDevice = () => {
return /android/i.test(navigator.userAgent.toLowerCase());
}
39、判断是Windows还是Mac系统
export const osType = () => {
const agent = navigator.userAgent.toLowerCase();
const isMac = /macintosh|mac os x/i.test(navigator.userAgent);
const isWindows = agent.indexOf("win64") >= 0 || agent.indexOf("wow64") >= 0 || agent.indexOf("win32") >= 0 || agent.indexOf("wow32") >= 0;
if (isWindows) {
return "windows";
}
if(isMac){
return "mac";
}
}
40、判断是否是微信/QQ内置浏览器
export const broswer = () => {
const ua = navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == "micromessenger") {
return "weixin";
} else if (ua.match(/QQ/i) == "qq") {
return "QQ";
}
return false;
}
41、 判断横竖屏
function hengshuping(){
if(window.orientation==180||window.orientation==0){
alert("Portrait state!")
}
if(window.orientation==90||window.orientation==-90){
alert("Landscape state!")
}
}
window.addEventListener("onorientationchange" in window ? "orientationchange" : "resize", hengshuping, false);
42、改变横竖屏的样式
<style>
@media all and (orientation : landscape) {
body {
background-color: #ff0000;
}
}
@media all and (orientation : portrait) {
body {
background-color: #00ff00;
}
}
</style>
43、浏览器型号和版本
export const getExplorerInfo = () => {
let t = navigator.userAgent.toLowerCase();
return 0 <= t.indexOf("msie") ? { //ie < 11
type: "IE",
version: Number(t.match(/msie ([\d]+)/)[1])
} : !!t.match(/trident\/.+?rv:(([\d.]+))/) ? { // ie 11
type: "IE",
version: 11
} : 0 <= t.indexOf("edge") ? {
type: "Edge",
version: Number(t.match(/edge\/([\d]+)/)[1])
} : 0 <= t.indexOf("firefox") ? {
type: "Firefox",
version: Number(t.match(/firefox\/([\d]+)/)[1])
} : 0 <= t.indexOf("chrome") ? {
type: "Chrome",
version: Number(t.match(/chrome\/([\d]+)/)[1])
} : 0 <= t.indexOf("opera") ? {
type: "Opera",
version: Number(t.match(/opera.([\d]+)/)[1])
} : 0 <= t.indexOf("Safari") ? {
type: "Safari",
version: Number(t.match(/version\/([\d]+)/)[1])
} : {
type: t,
version: -1
}
}
44、获取可视窗口宽度
export const getPageViewWidth = () => {
return (document.compatMode == "BackCompat" ? document.body : document.documentElement).clientWidth;
}
45、当前时间
export const nowTime = () => {
const now = new Date();
const year = now.getFullYear();
const month = now.getMonth();
const date = now.getDate() >= 10 ? now.getDate() : ('0' + now.getDate());
const hour = now.getHours() >= 10 ? now.getHours() : ('0' + now.getHours());
const miu = now.getMinutes() >= 10 ? now.getMinutes() : ('0' + now.getMinutes());
const sec = now.getSeconds() >= 10 ? now.getSeconds() : ('0' + now.getSeconds());
return +year + "年" + (month + 1) + "月" + date + "日 " + hour + ":" + miu + ":" + sec;
}
46、格式化时间
export const dateFormater = (formater, time) => {
let date = time ? new Date(time) : new Date(),
Y = date.getFullYear() + '',
M = date.getMonth() + 1,
D = date.getDate(),
H = date.getHours(),
m = date.getMinutes(),
s = date.getSeconds();
return formater.replace(/YYYY|yyyy/g, Y)
.replace(/YY|yy/g, Y.substr(2, 2))
.replace(/MM/g,(M<10 ? '0' : '') + M)
.replace(/DD/g,(D<10 ? '0' : '') + D)
.replace(/HH|hh/g,(H<10 ? '0' : '') + H)
.replace(/mm/g,(m<10 ? '0' : '') + m)
.replace(/ss/g,(s<10 ? '0' : '') + s)
}
// dateFormater('YYYY-MM-DD HH:mm:ss')
// dateFormater('YYYYMMDDHHmmss')
47、监听标签显示和隐藏的事件
const {hidden, visibilityChange} = (() => {
let hidden, visibilityChange;
if (typeof document.hidden !== "undefined") {
// Opera 12.10 and Firefox 18 and later support
hidden = "hidden";
visibilityChange = "visibilitychange";
} else if (typeof document.msHidden !== "undefined") {
hidden = "msHidden";
visibilityChange = "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
hidden = "webkitHidden";
visibilityChange = "webkitvisibilitychange";
}
return {
hidden,
visibilityChange
}
})();
const handleVisibilityChange = () => {
console.log("currently hidden", document[hidden]);
};
document.addEventListener(
visibilityChange,
handleVisibilityChange,
false
);
48、本地图片预览
<div class="test">
<input type="file" name="" id="">
<img src="" alt="">
</div>
<script>
const getObjectURL = (file) => {
let url = null;
if (window.createObjectURL != undefined) { // basic
url = window.createObjectURL(file);
} else if (window.URL != undefined) { // webkit or chrome
url = window.URL.createObjectURL(file);
} else if (window.URL != undefined) { // mozilla(firefox)
url = window.URL.createObjectURL(file);
}
return url;
}
document.querySelector('input').addEventListener('change', (event) => {
document.querySelector('img').src = getObjectURL(event.target.files[0])
})
</script>
49、元素可编辑
<div contenteditable="true">here can be edited</div>
50、激活应用
<a href="tel:12345678910">phone</a>
<a href="sms:12345678910,12345678911?body=hello">android message</a>
<a href="sms:/open?addresses=12345678910,12345678911&body=hello">ios message</a>
<a href="wx://">ios message</a>
51、随机颜色生成
const getRandomColor = () => `#${Math.floor(Math.random() * 0xffffff).toString(16)}`
getRandomColor() // '#4c2fd7'
52、颜色格式16进制转rgb
const hexToRgb = hex => hex.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i, (_, r, g, b) => `#${r}${r}${g}${g}${b}${b}`).substring(1).match(/.{2}/g).map((x) => parseInt(x, 16));
hexToRgb('#00ffff'); // [0, 255, 255]
hexToRgb('#0ff'); // [0, 255, 255]
53、将十六进制转换为rgba
const hexToRgba = hex => {
const [r, g, b] = hex.match(/\w\w/g).map(val => parseInt(val, 16))
return `rgba(${r}, ${g}, ${b}, 1)`;
}
hexToRgba('#000000') // rgba(0, 0, 0, 1)
hexToRgba('#ff007f') // rgba(255, 0, 127, 1)
54、将rgba转换为十六进制
const rgbaToHex = (r, g, b) => "#" + [r, g, b].map(num => parseInt(num).toString(16).padStart(2, '0')).join('')
rgbaToHex(0, 0 ,0) // #000000
rgbaToHex(255, 0, 127) //#ff007f
55、将内容复制到剪贴板
const copyToClipboard = (content) => navigator.clipboard.writeText(content)
copyToClipboard("Hello fatfish")
56、 获取鼠标选中内容
const getSelectedText = () => window.getSelection().toString()
getSelectedText()
57、获取多个数字的平均值
const average = (...args) => args.reduce((a, b) => a + b, 0) / args.length
average(0, 1, 2, -1, 9, 10) // 3.5
58、检查一个数字是偶数还是奇数
const isEven = num => num % 2 === 0
isEven(2) // true
isEven(1) // false
59、在数组中去重元素
const uniqueArray = (arr) => [...new Set(arr)]
uniqueArray([ 1, 1, 2, 3, 4, 5, -1, 0 ]) // [1, 2, 3, 4, 5, -1, 0]
60、检查一个对象是否为空对象
const isEmpty = obj => Reflect.ownKeys(obj).length === 0 && obj.constructor === Object
isEmpty({}) // true
isEmpty({ name: 'fatfish' }) // false
61、计算两个日期之间的间隔
const dayDiff = (d1, d2) => Math.ceil(Math.abs(d1.getTime() - d2.getTime()) / 86400000)
dayDiff(new Date("2023-06-23"), new Date("1997-05-31")) // 9519
62、找出日期所在的年份中的天数
const dayInYear = (d) => Math.floor((d - new Date(d.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24)
dayInYear(new Date('2023/06/23'))// 174
63、获取变量的类型
const typeOf = (obj) => Object.prototype.toString.call(obj).slice(8, -1).toLowerCase()
typeOf('') // string
typeOf(0) // number
typeOf() // undefined
typeOf(null) // null
typeOf({}) // object
typeOf([]) // array
typeOf(0) // number
typeOf(() => {}) // function
64、随机IP
const generateRandomIP = () => {
return Array.from({length: 4}, () => Math.floor(Math.random() * 256)).join('.');
}
generateRandomIP() // 220.187.184.113
generateRandomIP() // 254.24.179.151
65、a链接下载
const downloadByUrl = (url, filename) => {
if (!url) throw new Error('当前没有下载链接');
const a = document.createElement("a");
a.style.display = "none";
a.href = url;
a.download = filename;
// 使用target="_blank"时,添加rel="noopener noreferrer" 堵住钓鱼安全漏洞 防止新页面window指向之前的页面
a.rel = "noopener noreferrer";
document.body.append(a);
a.click();
setTimeout(() => {
a.remove();
}, 1000);
};
使用1(URL.createObjectURL[1] 可以给 File
或 Blob
生成一个URL,形式为 blob:<origin>/<uuid>
,此时浏览器内部就会为每个这样的 URL 存储一个 URL → Blob 的映射。因此,此类 URL 很短,但可以访问 Blob。)
import downloadByUrl from "@/utils/download";
const download = async () => {
const blob = await fetchFile();
// 生成访问 blob 的 URL
const url = URL.createObjectURL(blob);
// 调用刚刚封装的 a 标签下载方法
downloadByUrl(url, "表格文件.xlsx");
// 删除映射,释放内存
URL.revokeObjectURL(url);
};
使用2(转换为 base64(data:)FileReader 是一个对象,其唯一目的就是从 Blob 对象中读取数据,我们可以使用它的 readAsDataURL方法将 Blob 读取为 base64)
import downloadByUrl from "@/utils/download";
const download = async () => {
const blob = await fetchFile();
// 声明一个 fileReader
const fileReader = new FileReader();
// 将 blob 读取成 base64
fileReader.readAsDataURL(blob);
// 读取成功后 下载资源
fileReader.onload = function () {
downloadByUrl(fileReader.result);
};
};
export const fetchFile = async (params) => {
return axios.get(api, {
params,
responseType: "blob"
});
};
66、下载
/**
* @param: fileType - 文件类型
* @param: fileName - 文件名称
* @param: data - 数据流文件
**/
export function download(fileType, bucketName,data) {
let downType = "";
let downName = "";
if (fileType == "image") {
downType = "image/png";
downName = fileName + ".png";
} else if (fileType == "word") {
downType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
downName = fileName + ".docx";
} else if (fileType == "video") {
downType = "video/mpeg4";
downName = fileName + ".mp4";
} else if (fileType == "radio") {
downType = "audio/mpeg";
downName = fileName + ".mp3";
} else if (fileType == "pdf") {
downType = "application/pdf";
downName = fileName + ".pdf";
}
let blob = new Blob([data], { type: downType });
let downloadElement = document.createElement("a");
let href = window.URL.createObjectURL(blob);
downloadElement.href = href;
document.body.appendChild(downloadElement);
//downloadElement.setAttribute("download", downName);//设置下载名称
downloadElement.download = downName; //设置下载文件名称
downloadElement.click();
document.body.removeChild(downloadElement); //移除元素;防止连续点击创建多个a标签
window.URL.revokeObjectURL(href);
}
67、dayjs 获取某月份最后一天日期
let year = dayjs(new Date()).year()
let month= dayjs(new Date()).month()+1
this.form.endTime = dayjs(`${year}-${month}`).endOf('month').format('YYYY-MM-DD')