视频全屏
// 全屏
function fullScreen(el) {
const isFullscreen =
document.fullScreen ||
document.mozFullScreen ||
document.webkitIsFullScreen;
if (!isFullscreen) {
//进入全屏,多重短路表达式
(el.requestFullscreen && el.requestFullscreen()) ||
(el.mozRequestFullScreen && el.mozRequestFullScreen()) ||
(el.webkitRequestFullscreen && el.webkitRequestFullscreen()) ||
(el.msRequestFullscreen && el.msRequestFullscreen());
} else {
//退出全屏,三目运算符
document.exitFullscreen
? document.exitFullscreen()
: document.mozCancelFullScreen
? document.mozCancelFullScreen()
: document.webkitExitFullscreen
? document.webkitExitFullscreen()
: "";
}
}
找出数字在数组中下一个相邻的元素
let i = "";
let rr = [];
const name = (n, arr1)=>{
let num = Number(n);
for (let i = 0; i < arr1.length; i++) {
const element = arr1[i];
if (element != num) {
rr.push(num--);
}
}
return rr.find((el) => {
let newel = String(el);
return arr1.includes(newel);
})}
let arr = ["2", "4", "6", "8", "10", "12", "14", "16", "18", "20", "22", "24", "27", "30", "33", "36", "42", "48", "54", "60"]
console.log(name('5',arr)); //4
格式化时间
/**
* @param {number} time
* @param {string} option
* @returns {string}
*/
function formatTime(time, option) {
if (('' + time).length === 10) {
time = parseInt(time) * 1000
} else {
time = +time
}
const d = new Date(time)
const now = Date.now()
const diff = (now - d) / 1000
if (diff < 30) {
return '刚刚'
} else if (diff < 3600) {
// less 1 hour
return Math.ceil(diff / 60) + '分钟前'
} else if (diff < 3600 * 24) {
return Math.ceil(diff / 3600) + '小时前'
} else if (diff < 3600 * 24 * 2) {
return '1天前'
}
if (option) {
return parseTime(time, option)
} else {
return (
d.getMonth() +
1 +
'月' +
d.getDate() +
'日' +
d.getHours() +
'时' +
d.getMinutes() +
'分'
)
}
}
解析时间
/**
* Parse the time to string
* @param {(Object|string|number)} time
* @param {string} cFormat
* @returns {string | null}
*/
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 {
// support safari
// https://stackoverflow.com/questions/4310953/invalid-date-in-safari
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
}
解析Url地址
/**
* @param {string} url
* @returns {Object}
*/
function param2Obj(url) {
const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
if (!search) {
return {}
}
const obj = {}
const searchArr = search.split('&')
searchArr.forEach(v => {
const index = v.indexOf('=')
if (index !== -1) {
const name = v.substring(0, index)
const val = v.substring(index + 1, v.length)
obj[name] = val
}
})
return obj
}
合并两个对象
/**
* Merges two objects, giving the last one precedence
* @param {Object} target
* @param {(Object|Array)} source
* @returns {Object}
*/
function objectMerge(target, source) {
if (typeof target !== 'object') {
target = {}
}
if (Array.isArray(source)) {
return source.slice()
}
Object.keys(source).forEach(property => {
const sourceProperty = source[property]
if (typeof sourceProperty === 'object') {
target[property] = objectMerge(target[property], sourceProperty)
} else {
target[property] = sourceProperty
}
})
return target
}
数组去重
/**
* @param {Array} arr
* @returns {Array}
*/
function uniqueArr(arr) {
return Array.from(new Set(arr))
}
防抖
在一定时间间隔内,多次调用一个方法,只会执行一次.
/**
* @param {Function} func
* @param {number} wait
* @param {boolean} immediate
* @return {*}
*/
function debounce(func, wait, immediate) {
let timeout, args, context, timestamp, result
const later = function() {
// 据上一次触发时间间隔
const last = +new Date() - timestamp
// 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
if (last < wait && last > 0) {
timeout = setTimeout(later, wait - last)
} else {
timeout = null
// 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
if (!immediate) {
result = func.apply(context, args)
if (!timeout) context = args = null
}
}
}
return function(...args) {
context = this
timestamp = +new Date()
const callNow = immediate && !timeout
// 如果延时不存在,重新设定延时
if (!timeout) timeout = setTimeout(later, wait)
if (callNow) {
result = func.apply(context, args)
context = args = null
}
return result
}
}
/**
* 防抖
* @param {Function} func 要执行的回调函数
* @param {Number} wait 延时的时间
* @param {Boolean} immediate 是否立即执行
* @return null
*/
let timeout;
export default function Debounce(func, wait = 3000, immediate = true) {
// 清除定时器
if (timeout !== null) clearTimeout(timeout);
// 立即执行,此类情况一般用不到
if (immediate) {
var callNow = !timeout;
timeout = setTimeout(function() {
timeout = null;
}, wait);
if (callNow) typeof func === 'function' && func();
} else {
// 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法
timeout = setTimeout(function() {
typeof func === 'function' && func();
}, wait);
}
}
//使用
Debounce(()=>{
console.log(1);
});
节流
多次调用方法,按照一定的时间间隔执行
// ①定时器实现
const throttle = (fn,delay = 500) =>{
let flag = true;
return (...args) => {
if(!flag) return;
flag = false;
setTimeout(() => {
fn.apply(this,args);
flag = true;
},delay);
};
}
// ②时间戳实现
const throttle = (fn,delay = 500) => {
let preTime = Date.now();
return (...args) => {
const nowTime = Date.now();
if(nowTime - preTime >= delay){
preTime = Date.now();
fn.apply(this,args);
}
}
}
简易搜索
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text" id="int">
</body>
<script>
let list = ["示例1","示例12","示例5","示例56"];
document.querySelector('#int').onchange=function(e){
console.log(search(e.target.value));
}
function search(val) {
if (val) {
return list.filter(function (item) {
return Object.keys(item).some(function (key) {
return String(item[key]).toLowerCase().indexOf(val) > -1
})
})
}
return list
}
</script>
</html>
将秒化为时分秒
function formateSeconds (endTime) {
let secondTime = parseInt(endTime); //将传入的秒的值转化为Number
let min = 0; // 初始化分
let h = 0; // 初始化小时
let result = "";
if (secondTime > 60) {
//如果秒数大于60,将秒数转换成整数
min = parseInt(secondTime / 60); //获取分钟,除以60取整数,得到整数分钟
secondTime = parseInt(secondTime % 60); //获取秒数,秒数取佘,得到整数秒数
if (min > 60) {
//如果分钟大于60,将分钟转换成小时
h = parseInt(min / 60); //获取小时,获取分钟除以60,得到整数小时
min = parseInt(min % 60); //获取小时后取佘的分,获取分钟除以60取佘的分
}
}
result = `${h.toString().padStart(2, "0")}:${min.toString().padStart(2, "0")}:${secondTime.toString().padStart(2, "0")}`;
return result;
}
将时分秒化为秒
function formSeconds (times) {
let arr = times.split(":");
let s = arr[2];
let m = arr[1];
let h = arr[0];
let m1 = m<10?m.replace(/\b(0+)/gi,""):m;
let h1 = h<10?h.replace(/\b(0+)/gi,""):h;
return m1*60+Number(h1)+Number(s)
}
对象深层遍历
var obj = {
a:{
b:{
c:"maomin"
}
}
}
const safeGet = (obj, path) => {
try {
return path.split('.').reduce((o, k) => o[k], obj)
} catch (e) {
return undefined
}
}
console.log(safeGet(obj,'a.b.c'));// maomin
带有分割符的字符串转化成一个n维数组
var str = "A-2-12";
var str1 = str.split('-');
var arr = str1.reverse().reduce((pre,cur,i) => {
if(i==0)
{ pre.push(cur)
return pre
}
return [cur,pre]
},[])
console.log(arr) // ["A"["B",["C"]]]
获取时间戳
function thedata(d){
return d.replace(/\-/g, "\/")
}
var serverTime = parseInt(new Date(thedata('2020-08-12 15:52:11')).valueOf());
console.log(serverTime); // 1597218731000,获取到时间戳
对象深拷贝
function deepClone(target) {
// 定义一个变量
let result;
// 如果当前需要深拷贝的是一个对象的话
if (typeof target === 'object') {
// 如果是一个数组的话
if (Array.isArray(target)) {
result = []; // 将result赋值为一个数组,并且执行遍历
for (let i in target) {
// 递归克隆数组中的每一项
result.push(deepClone(target[i]))
}
// 判断如果当前的值是null的话;直接赋值为null
} else if(target===null) {
result = null;
// 判断如果当前的值是一个RegExp对象的话,直接赋值
} else if(target.constructor===RegExp){
result = target;
}else {
// 否则是普通对象,直接for in循环,递归赋值对象的所有值
result = {};
for (let i in target) {
result[i] = deepClone(target[i]);
}
}
// 如果不是对象的话,就是基本数据类型,那么直接赋值
} else {
result = target;
}
// 返回最终结果
return result;
}
简易版对象拷贝
function copy(obj) {
if(typeof obj == "object") { //判断是否复杂类型
var result = obj.constructor == Array ? [] : {};//判断数组类型或是object,数组即result=[],object即result={}
for(let i in obj) {
result[i] = typeof obj[i] == "object" ? copy(obj[i]) : obj[i]//判断数据每一项是否是object
}
} else {
var result = obj //基本类型直接拷贝
}
return result;
}
实现一个模板引擎
function render(template, data) {
const reg = /\{\{(\w+)\}\}/; // 模板字符串正则
if (reg.test(template)) { // 判断模板里是否有模板字符串
const name = reg.exec(template)[1]; // 查找当前模板里第一个模板字符串的字段
template = template.replace(reg, data[name]); // 将第一个模板字符串渲染
return render(template, data); // 递归的渲染并返回渲染后的结构
}
return template; // 如果模板没有模板字符串直接返回
}
let template = '我是{{name}},年龄{{age}},性别{{sex}}';
let data = {
name: '姓名',
age: 18
}
render(template, data); // 我是姓名,年龄18,性别undefined
封装fetch
/**
* 封装fetch函数,用Promise做回调
* @type {{get: (function(*=)), post: (function(*=, *=))}}
*/
const fetchUtil = {
get: (url) => {
return new Promise((resolve, reject) => {
fetch(url, {
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
}
}).then((response) => response.json()).then(response => {
resolve(response);
}).catch(err => {
reject(new Error(err));
});
});
},
post: (url, params) => {
return new Promise((resolve, reject) => {
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: params
}).then((response) => response.json()).then(response => {
resolve(response);
}).catch(err => {
reject(new Error(err));
});
});
}
};
判断浏览器环境
function getSystem(){
const mac = /mac/i,
linux = /linux/i,
win = /win/i;
const platform = navigator.platform.toLowerCase();
if(mac.test(platform)){
return 'MAC';
} else if(win.test(platform)){
return 'WIN';
} else if(linux.test(platform)){
return 'Linux';
}
return undefined;
}
const browser = {
versions:function(){
let ret = 'xxSys';
const u = navigator.userAgent;
const isMobile = !!u.match(/AppleWebKit.*Mobile.*/),
ios = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/),
android = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1;
if(isMobile){
if(ios) return 'IOS';
if(android) return 'Android';
} else {
ret = getSystem() || ret;
}
return ret;
}(),
};
定义数组内部对象形式
const objArrtransArr = (olddata, oldval, oldname)=>{
const newArr = [];
olddata.forEach(item => {
// 定义数组内部对象形式
let obj = {};
obj.value = item[oldval];
obj.name = item[oldname];
// 将对象数据推到数组中
newArr.push(obj);
});
return newArr;
}
解析html字符串
function (htmlobj) {
var el = document.createElement('div');
el.innerHTML = htmlobj;
var tags = el.getElementsByTagName('img');
var text = tags[0].getAttribute("src");
return text;
}
判断浏览器是否支持摄像头
function videoCheck () {
var deviceList = [];
navigator.mediaDevices
.enumerateDevices()
.then(devices => {
devices.forEach(device => {
deviceList.push(device.kind);
});
if (deviceList.indexOf("videoinput") == "-1") {
console.info("没有摄像头");
return false;
} else {
console.info("有摄像头");
}
})
.catch(function(err) {
alert(err.name + ": " + err.message);
});
}
回文算法
//忽略标点符号、大小写和空格,正着读和反着读一模一样。
function made(str) {
var str1 = str.toLowerCase(); //先将字符串全部转换为小写
var reg = /[\W\_]/g; // 删除所有非字母数字字符和下划线
var str2 = str1.replace(reg, ""); // 去掉非字母和非数字
var str3 = str2.split(""); // 字符串分隔成数组
var str4 = str3.reverse(); // 反转数组中的元素
var str5 = str4.join(""); // 反转后的数组转化为字符串
return str2 === str5;
}
函数只执行一次
function once (fn){
let called = false
return function () {
if (!called) {
called = true
fn.apply(this, arguments)
}
}
}
function func (){
console.log(1);
}
//调用闭包函数
let onlyOnce = once(func);
onlyOnce(); // 1
onlyOnce();
构造函数回调方法
function Watcher(cb){
this.cb = cb;
}
Watcher.prototype.get=function(data){
this.cb(data);
}
new Watcher((v)=>{
console.log(v);
}).get('admin');
用 apply 将数组各项添加到另一个数组
var array = ['a', 'b'];
var elements = [0, 1, 2];
array.push.apply(array, elements);
console.info(array); // ["a", "b", 0, 1, 2]
微信JS-SDK 调用
import wx from 'weixin-js-sdk' //引入微信js-sdk
import { getWXSignature } from '../request/api'
const custom = function(url, jsApiList) {
return getWXConfig(url, jsApiList)
}
function getWXConfig(url, jsApiList) {
getWXSignature({ url })
.then(res => {
let { appId, timestamp, noncestr, signature } = res.data
console.log(appId, timestamp, noncestr, signature, jsApiList, url)
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: appId, // 必填,公众号的唯一标识
timestamp: timestamp, // 必填,生成签名的时间戳
nonceStr: noncestr, // 必填,生成签名的随机串
signature: signature, // 必填,签名
jsApiList: jsApiList, // 必填,需要使用的JS接口列表
})
wx.error(function(res) {
console.log('wxerr', res)
})
})
.catch(err => {
console.log(err)
})
}
export default custom
// ***
getWeiXinConfig() {
let url = window.location.href
// let url = encodeURIComponent(location.href.split('#')[0])
this.$getWXConfig(url, ['scanQRCode'])
}
//微信扫一扫
wxSweep() {
wx.scanQRCode({
needResult: 1, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
scanType: ['barCode'], //'qrCode', 可以指定扫二维码还是一维码,默认二者都有
success: function(res) {
var result = res.resultStr // 当needResult 为 1 时,扫码返回的结果
console.log(result)
if (this.type === 1) {
//位置上传
this.$router.push({
path: '/updateLocation',
query: {
projectId: this.projectId,
type: 1,
mac: result,
},
})
} else if (this.type === 2) {
//模块更换
this.$router.push({
path: '/changeModule',
query: {
projectId: this.projectId,
type: 1,
mac: result,
},
})
} else {
//开关更换
this.$router.push({
path: '/changeSwitch',
query: {
projectId: this.projectId,
type: 1,
mac: result,
},
})
}
},
})
},
js 递归数组降维
let children = [1, [2, 3], [4, [5, 6, [7, 8]]], [9, 10]];
function simpleNormalizeChildren(children) {
for (let i = 0; i < children.length; i++) {
if (Array.isArray(children[i])) {
children = Array.prototype.concat.apply([], children);
simpleNormalizeChildren(children)
}
}
return children;
}
console.log(simpleNormalizeChildren(children));
simpleNormalizeChildren(children); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
js 数组降维(二维降一维)
function simpleNormalizeChildren(children) {
for (let i = 0; i < children.length; i++) {
if (Array.isArray(children[i])) {
return Array.prototype.concat.apply([], children)
}
}
return children
}
let arrs = [
[
'1'
],
[
'3'
]
];
const arr = simpleNormalizeChildren(arrs);
console.log(arr); // ['1','3']
File对象 转 base64
inputImage(e) {
let img = e.target.files[0];
if (img) {
this.blobToDataURL(img);
}
},
blobToDataURL(blob) {
let reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = function(evt) {
let base64 = evt.target.result;
console.log(base64);
};
},
Vue3
const oDiv = document.createElement('div');
const oScript = document.createElement('script');
oDiv.setAttribute('id', 'app');
oScript.type = 'text/javascript';
oScript.src = "https://unpkg.com/vue@next";
document.body.appendChild(oDiv);
document.body.appendChild(oScript);
window.onload = function () {
const { createApp,ref } = Vue;
const App = {
template: `
<div>{{msg}}</div>
<p>{{count}}</p>
`,
data(){
return {
msg:'maomin'
}
},
setup(){
let count = ref(0);
return {
count
}
}
}
createApp(App).mount('#app');
}
递归寻找操作(已删除指定项为例)
// 递归寻找
recursion(data, id) {
let result;
if (!data) {
return;
}
for (let i = 0; i < data.length; i++) {
let item = data[i];
if (item.breakerId === id) {
result = item;
data.splice(i, 1);
break;
} else if (item.childrenBranch && item.childrenBranch.length > 0) {
result = this.recursion(item.childrenBranch, id);
if (result) {
return result;
}
}
}
return result;
},
递归数组,将数组为空设为undefined
function useTree(data) {
for (let index = 0; index < data.length; index++) {
const element = data[index];
if (element.childrenBranch.length < 1) {
element.childrenBranch = undefined;
} else {
useTree(element.childrenBranch);
}
}
return data;
}
数组对象中相同属性值的个数
group(arr) {
var obj = {};
if (Array.isArray(arr)) {
for (var i = 0; i < arr.length; ++i) {
var isNew = arr[i].isNew;
if (isNew in obj) obj[isNew].push(arr[i]);
else obj[isNew] = [arr[i]];
}
}
return obj;
},
max(obj) {
var ret = 0;
if (obj && typeof obj === "object") {
for (var key in obj) {
var length = obj[key].length;
if (length > ret) ret = length;
}
}
return ret;
},
var data = [
{
addr: "1",
isNew: false,
},
{
addr: "2",
isNew: false,
}
]
max(group(data) // 2
检测版本是vue3
import { h } from 'vue';
const isVue3 = typeof h === 'function';
console.log(isVue3)
检测数据对象中是否有空对象
let arr = [{},{name:'1'}]
const arr = this.bannerList.filter(item =>
item == null || item == '' || JSON.stringify(item) == '{}'
);
console.log(arr.length > 0 ? '不通过' : '通过')
深拷贝
/* @param {*} obj
* @param {Array<Object>} cache
* @return {*}
*/
function deepCopy (obj, cache = []) {
// just return if obj is immutable value
if (obj === null || typeof obj !== 'object') {
return obj
}
// if obj is hit, it is in circular structure
const hit = find(cache, c => c.original === obj)
if (hit) {
return hit.copy
}
const copy = Array.isArray(obj) ? [] : {}
// put the copy into cache at first
// because we want to refer it in recursive deepCopy
cache.push({
original: obj,
copy
})
Object.keys(obj).forEach(key => {
copy[key] = deepCopy(obj[key], cache)
})
return copy
}
const objs = {
name:'maomin',
age:'17'
}
console.log(deepCopy(objs));
h5文字转语音
speech(txt){
var synth = null;
var msg = null;
synth = window.speechSynthesis;
msg = new SpeechSynthesisUtterance();
msg.text = txt;
msg.lang = "zh-CN";
synth.speak(msg);
if(window.speechSynthesis.speaking){
console.log("音效有效");
} else {
console.log("音效失效");
}
}
模糊搜索
recursion(data, name) {
let result;
if (!data) {
return;
}
for (var i = 0; i < data.length; i++) {
let item = data[i];
if (item.name.toLowerCase().indexOf(name) > -1) {
result = item;
break;
} else if (item.children && item.children.length > 0) {
result = this.recursion(item.children, name);
if (result) {
return result;
}
}
}
return result;
},
onSearch(v) {
if (v) {
if (!this.recursion(this.subtable, v)) {
this.$message({
type: 'error',
message: '搜索不到',
});
} else {
this.tableData = [this.recursion(this.subtable, v)];
}
}
},
input 数字类型
<el-input
v-model.number="form.redVal"
type="number"
@keydown.native="channelInputLimit"
placeholder="请输入阈值设定"
maxlength="8"
></el-input>
channelInputLimit(e) {
let key = e.key;
// 不允许输入‘e‘和‘.‘
if (key === 'e' || key === '.') {
e.returnValue = false;
return false;
}
return true;
},
排序(交换位置)
const list = [1,2,3,4,5,6];
function useChangeSort (arr,oldIndex,newIndex){
const targetRow = arr.splice(oldIndex, 1)[0];
const targetRow1 = arr.splice(newIndex, 1)[0];
arr.splice(newIndex, 0, targetRow);
arr.splice(oldIndex, 0, targetRow1);
return arr
}
console.log(useChangeSort(list,5,0)); // [6, 2, 3, 4, 5, 1]
格式化时间
/**
* Parse the time to string
* @param {(Object|string|number)} time
* @param {string} cFormat
* @returns {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 {
// support safari
// https://stackoverflow.com/questions/4310953/invalid-date-in-safari
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;
}
将对象的值收集到数组中
const info = { name: "Matt", country: "Finland", age: 35 };
// LONGER FORM
let data = [];
for (let key in info) {
data.push(info[key]);
}
// SHORTHAND
const data = Object.values(info);
检查一个项目是否存在于数组中
let numbers = [1, 2, 3];
// LONGER FORM
const hasNumber1 = numbers.indexOf(1) > -1 // -> True
// SHORTHAND/CLEANER APPROACH
const hasNumber1 = numbers.includes(1) // -> True
压缩多个条件
const num = 1;
// LONGER FORM
if(num == 1 || num == 2 || num == 3){
console.log("Yay");
}
// SHORTHAND
if([1,2,3].includes(num)){
console.log("Yay");
}
指数运算符
// LONGER FORM
Math.pow(4,2); // 16
Math.pow(2,3); // 8
// SHORTHAND
4**2 // 16
2**3 // 8
Math.floor() 简写
// LONG FORM
Math.floor(5.25) // -> 5.0
// SHORTHAND
~~5.25 // -> 5.0
用一行代码分配多个值
let num1, num2;
// LONGER FORM
num1 = 10;
num2 = 100;
// SHORTHAND
[num1, num2] = [10, 100];
从数组中查找特定元素
const fruits = [
{ type: "Banana", color: "Yellow" },
{ type: "Apple", color: "Green" }
];
// LONGER FORM
let yellowFruit;
for (let i = 0; i < fruits.length; ++i) {
if (fruits[i].color === "Yellow") {
yellowFruit = fruits[i];
}
}
// SHORTHAND
yellowFruit = fruits.find((fruit) => fruit.color === "Yellow");
类固醇的字符串
const age = 41;
const sentence = `I'm ${age} years old`;
let num1 = 20;
let num2 = 10;
console.log(`Sum = ${num1 + num2} and Subtract = ${num1 - num2}`);
//=> Sum = 30 and Subtract = 10
// result: I'm 41 years old
获取文件后缀名
/**
* 获取文件后缀名
* @param {String} filename
*/
export function getExt(filename) {
if (typeof filename == 'string') {
return filename
.split('.')
.pop()
.toLowerCase()
} else {
throw new Error('filename must be a string type')
}
}
//使用方式
getExt("1.mp4") //->mp4
复制内容到剪贴板
export function copyToBoard(value) {
const element = document.createElement('textarea')
document.body.appendChild(element)
element.value = value
element.select()
if (document.execCommand('copy')) {
document.execCommand('copy')
document.body.removeChild(element)
return true
}
document.body.removeChild(element)
return false
}
//如果复制成功返回true
copyToBoard('lalallala')
休眠多少毫秒
/**
* 休眠xxxms
* @param {Number} milliseconds
*/
export function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
//使用方式
const fetchData=async()=>{
await sleep(1000)
}
生成随机字符串
/**
* 生成随机id
* @param {*} length
* @param {*} chars
*/
export function uuid(length, chars) {
chars =
chars ||
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
length = length || 8
var result = ''
for (var i = length; i > 0; --i)
result += chars[Math.floor(Math.random() * chars.length)]
return result
}
//第一个参数指定位数,第二个字符串指定字符,都是可选参数,如果都不传,默认生成8位
uuid()
简单的深拷贝
/**
*深拷贝
* @export
* @param {*} obj
* @returns
*/
export function deepCopy(obj) {
if (typeof obj != 'object') {
return obj
}
if (obj == null) {
return obj
}
return JSON.parse(JSON.stringify(obj))
}
const person={name:'xiaoming',child:{name:'Jack'}}
deepCopy(person) //new person
数组去重
/**
* 数组去重
* @param {*} arr
*/
export function uniqueArray(arr) {
if (!Array.isArray(arr)) {
throw new Error('The first parameter must be an array')
}
if (arr.length == 1) {
return arr
}
return [...new Set(arr)]
}
uniqueArray([1,1,1,1,1])//[1]
对象转化为FormData对象
/**
* 对象转化为formdata
* @param {Object} object
*/
export function getFormData(object) {
const formData = new FormData()
Object.keys(object).forEach(key => {
const value = object[key]
if (Array.isArray(value)) {
value.forEach((subValue, i) =>
formData.append(key + `[${i}]`, subValue)
)
} else {
formData.append(key, object[key])
}
})
return formData
}
let req={
file:xxx,
userId:1,
phone:'15198763636',
//...
}
fetch(getFormData(req))
保留到小数点以后n位
// 保留小数点以后几位,默认2位
export function cutNumber(number, no = 2) {
if (typeof number != 'number') {
number = Number(number)
}
return Number(number.toFixed(no))
}
后台管理中常用的工具类函数
校验数据类型
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
防抖
export const debounce = (() => {
let timer = null
return (callback, wait = 800) => {
timer&&clearTimeout(timer)
timer = setTimeout(callback, wait)
}
})()
示例:
如 vue 中使用
methods: {
loadList() {
debounce(() => {
console.log('加载数据')
}, 500)
}
}
节流
export const throttle = (() => {
let last = 0
return (callback, wait = 800) => {
let now = +new Date()
if (now - last > wait) {
callback()
last = now
}
}
})()
手机号脱敏
export const hideMobile = (mobile) => {
return mobile.replace(/^(\d{3})\d{4}(\d{4})$/, "$1****$2")
}
开启全屏
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()
}
}
关闭全屏
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()
}
}
大小写转换
//参数:
//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
解析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"}
判断手机是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;
}
数组对象根据字段去重
//参数:
//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: '张麻子' }]
滚动到页面顶部
export const scrollToTop = () => {
const height = document.documentElement.scrollTop || document.body.scrollTop;
if (height > 0) {
window.requestAnimationFrame(scrollToTop);
window.scrollTo(0, height - height / 8);
}
}
滚动到元素位置
export const smoothScroll = element =>{
document.querySelector(element).scrollIntoView({
behavior: 'smooth'
});
};
//示例:
smoothScroll('#target'); // 平滑滚动到 ID 为 target 的元素
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
金额格式化
//参数:
//{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
存储操作
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()
模糊搜索
//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: '树哥'}]
遍历树节点
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"}