foreword
In daily development, in the face of various needs, we often use some tool functions that have been developed before. Collecting these tool functions will greatly improve our development efficiency.
1. Verify data type
export const typeOf = function(obj) {
return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase()
}
Example:
typeOf('树哥') // string
typeOf([]) // array
typeOf(new Date()) // date
typeOf(null) // null
typeOf(true) // boolean
typeOf(() => {
}) // function
2. Anti-shake
export const debounce = (() => {
let timer = null
return (callback, wait = 800) => {
timer&&clearTimeout(timer)
timer = setTimeout(callback, wait)
}
})()
Example:
As used in vue
methods: {
loadList() {
debounce(() => {
console.log('加载数据')
}, 500)
}
}
3. Throttling
export const throttle = (() => {
let last = 0
return (callback, wait = 800) => {
let now = +new Date()
if (now - last > wait) {
callback()
last = now
}
}
})()
4. Mobile phone number desensitization
export const hideMobile = (mobile) => {
return mobile.replace(/^(\d{3})\d{4}(\d{4})$/, "$1****$2")
}
5. Turn on full screen
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()
}
}
6. Close full screen
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()
}
}
7. Case conversion
parameter:
str string to be converted
type 1-all uppercase 2-all lowercase 3-first letter uppercase
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
}
}
Example:
turnCase('vue', 1) // VUE
turnCase('REACT', 2) // react
turnCase('vue', 3) // Vue
8. Parsing URL parameters
export const getSearchParams = () => {
const searchPar = new URLSearchParams(window.location.search)
const paramsObj = {
}
for (const [key, value] of searchPar.entries()) {
paramsObj[key] = value
}
return paramsObj
}
Example:
// Suppose you are currently at https://****com/index?id=154513&age=18;
getSearchParams(); // {id: “154513”, age: “18”}
9. Determine whether the mobile phone is Android or 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. Array objects are deduplicated according to fields
parameter:
arr The array key to be deduplicated
According to the deduplicated field name
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
}
Example:
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. Scroll to the top of the page
export const scrollToTop = () => {
const height = document.documentElement.scrollTop || document.body.scrollTop;
if (height > 0) {
window.requestAnimationFrame(scrollToTop);
window.scrollTo(0, height - height / 8);
}
}
12. Scroll to element position
export const smoothScroll = element =>{
document.querySelector(element).scrollIntoView({
behavior: 'smooth'
});
};
Example:
smoothScroll('#target'); //Smoothly scroll to the element whose ID is target
Copy code
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)
}
Example:
uuid() // a640be34-689f-4b98-be77-e3972f9bffdd
But one thing to complain about is that uuid should generally be generated by the backend
14. Amount formatting
parameter:
{
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)
}
Example:
moneyFormat(10000000) // 10,000,000.00
moneyFormat(10000000, 3, '.', '-') // 10-000-000.000
15. Storage operation
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 }
Example:
localCache.getItem('user')
sessionCache.setItem('name','树哥')
sessionCache.getItem('token')
localCache.clear()
16. Download files
parameter:
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.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);
})
}`
use:
downloadFile('/api/download', {id}, 'filename')
Copy code
17. Time operation
Regarding time operation, there is no need to write a large series of codes yourself. It is strongly recommended to use day.js[2]
Day.js is a lightweight JavaScript time and date processing library with a size of only 2kb, which requires less JavaScript to download, parse and execute, leaving more time for code.
18. Deep copy
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);
};
Copy code
This method has some limitations: some special cases are not handled: such as Buffer object, Promise, Set, Map.
If you really want a complete deep copy, it is recommended to use the cloneDeep method in lodash.
19. Fuzzy search
parameters:
list The original array
keyWord The keyword
attribute array of the query needs to retrieve attributes
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
}
Example:
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: '树哥'}]
Copy code
20, traverse tree nodes
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)
}
}
}
Example:
Suppose we want to find the node with id 9 from the tree structure data
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"}