这里存放常用的工具函数
1.节流函数
/** 函数节流
* @param { function } fn 要节流的函数
* @param { number } interval 时间间隔,每个时间间隔内至多执行一次, 并使用最后一次调用时传入的参数
* @returns { function } 节流函数
*/
export const throttle = function (fn, interval = 1000 / 30) {
let timer = null
let params = null
return function (...args) {
params = args
if (timer) {
return
}
timer = setTimeout(() => {
fn.apply(this, params)
timer = null
}, interval)
}
}
2.全局绑定键盘事件
/**
* 全局键盘事件绑定
* @params {eventName: 事件名, key: 按下的按键, callback:回调}
* @returns { functions }
*/
export function keyboardEvent({ eventName, key, callback }) {
const handler = function (event) {
if (key) {
if (key === event.key) {
callback(event);
}
} else {
callback(event);
}
};
window.addEventListener(eventName, handler);
return function () {
window.removeEventListener(eventName, handler);
};
}
// 调用
keyboardEvent({
eventName: 'keydown',
key: 'Escape',
callback: () => {
this.$emit('close');
},
});
3.获取cookie
/**
* @description 通过名称查询cookie信息
* @parmas {name} cookie名称
* @return {String} cookie值
*/
const getCookieByName = (name) => {
let prefix = name + "="
let start = document.cookie.indexOf(prefix)
if (start === -1) return null;
let end = document.cookie.indexOf(";", start + prefix.length)
if (end === -1) {
end = document.cookie.length;
}
let value = document.cookie.substring(start + prefix.length, end)
return unescape(value);
}
4.判断是否为空对象的几种方法
function isEmptyObject(object) {
return JSON.stringify(object) === "{}";
}
function isEmptyObject2(object) {
for (const key in object) {
return false;
}
return true;
}
function isEmptyObject3(object) {
return Object.getOwnPropertyNames(object).length === 0;
}
function isEmptyObject4(object) {
return Object.keys(object).length === 0;
}
5.给元素绑定事件
此方法来源于Element-ui 源码当中
const on = (function() {
if (document.addEventListener) {
return function(element, event, handler) {
if (element && event && handler) {
element.addEventListener(event, handler, false)
}
}
} else {
return function(element, event, handler) {
if (element && event && handler) {
element.attachEvent('on' + event, handler)
}
}
}
})()
const off = (function() {
if (document.removeEventListener) {
return function(element, event, handler) {
if (element && event) {
element.removeEventListener(event, handler, false)
}
}
} else {
return function(element, event, handler) {
if (element && event) {
element.detachEvent('on' + event, handler)
}
}
}
})()
// 用法
const mousedownHandler = (event) => {
console.log(event)
}
on(document.getElementById('id'), 'mousedown', mousedownHandler)
off(document.getElementById('id'), 'mousedown', mousedownHandler)
6.使用clipboard
import Clipboard from 'clipboard'
const VueClipboardConfig = {
autoSetContainer: false,
appendToBody: true // This fixes IE, see #50
}
function copyText(text, container) {
return new Promise(function(resolve, reject) {
var fakeElement = document.createElement('button')
var clipboard = new Clipboard(fakeElement, {
text: function() { return text },
action: function() { return 'copy' },
container: typeof container === 'object' ? container : document.body
})
clipboard.on('success', function(e) {
clipboard.destroy()
resolve(e)
})
clipboard.on('error', function(e) {
clipboard.destroy()
reject(e)
})
if (VueClipboardConfig.appendToBody) document.body.appendChild(fakeElement)
fakeElement.click()
if (VueClipboardConfig.appendToBody) document.body.removeChild(fakeElement)
})
}
// 用法
copyText('data').then(res => {
console.log('复制成功')
}, error => {
console.log('复制失败’)
})
7.数组分割
function Chunk(arr = [], size = 1) {
return arr.length ? arr.reduce((t, v) => (t[t.length - 1].length === size ? t.push([v]) : t[t.length - 1].push(v), t), [[]]) : []; }
// 用法
const arr = [1, 2, 3, 4, 5];
Chunk(arr, 2); // [[1, 2], [3, 4], [5]]
8.Url 参数反序列化
function ParseUrlSearch() {
return location.search
.replace(/(^\?)|(&$)/g, "")
.split("&")
.reduce((t, v) => {
const [key, val] = v.split("=");
t[key] = decodeURIComponent(val);
return t;
}, {});
}
// 假设URL为:https://www.baidu.com?age=25&name=TYJ
ParseUrlSearch(); // { age: "25", name: "TYJ" }
9.Url参数序列化
function StringifyUrlSearch(search = {}) {
return Object.entries(search)
.reduce(
(t, v) => {
return `${t}${v[0]}=${encodeURIComponent(v[1])}&`;
},
Object.keys(search).length ? "?" : ""
)
.replace(/&$/, "");
}
const res = StringifyUrlSearch({ age: 27, name: "YZW" });
console.log(res); // ?age=27&name=YZW
10.字符串指定位置插入内容
function insertStrByIndex(source,index,target) {
return source.slice(0,index) + target + source.slice(index)
}
11.通过 Blob 下载文件
function downloadByBlob(filename = '文件名', blobData) {
const blob = new Blob([blobData], { type: "application/json" });
let dom = document.createElement("a");
let url = window.URL.createObjectURL(blob);
dom.href = url;
dom.download = decodeURI(filename);
dom.style.display = "none";
document.body.appendChild(dom);
dom.click();
dom.parentNode.removeChild(dom);
window.URL.revokeObjectURL(url);
}
12.字符串根据最后一次出现的位置分割(split by last)
输入:123.2345.34
输出:['123.2345', '34']
var array = '123.2345.34'.split(/.(?=[^.]+$)/);
console.log(array);
13.颠倒对象的key,value的两种方法
function invert(obj) {
// 这里, 对象的key 可以使用 [] 来表示
return Object.keys(obj).reduce((res, key) => Object.assign(res, { [obj[key]]: key}), {})
}
function invert2(obj) {
return Object.fromEntries(Object.entries(obj).map(([key, value]) => [value, key]))
}
const res1 = invert({ a: '1', b: '2', c: '3' })
const res2 = invert2({ a: '1', b: '2', c: '3' })
console.log(res1);
console.log(res2);
14.根据指定的key 忽略对象的一部分属性
// 根据指定的key 忽略对象的一部分属性
// omit a subset of properties of an object
function omit(obj, keys) {
return Object.keys(obj)
.filter(v => !keys.includes(v))
.reduce((res, key) => Object.assign(res, { [key]: obj[key] }), {})
}
const res = omit({ name: 'name', age: 12, sex: 'man' }, ['name', 'age'])
console.log(res); // {sex: 'man' }
15.根据指定的key 获取对象的一部分属性
// 根据指定的key, 获取对象的的一部分属性
// pick a subset of properties of an object
function pick(obj, keys) {
return Object.keys(obj)
.filter(key => keys.includes(key))
.reduce((res, key) => Object.assign(res, { [key]: obj[key]}),{})
}
const res = pick({ a: "1", b: "2", c: "3" }, ["a", "b"]);
console.log(res); // a: '1', b: '2' }
16.去除对象中所有的 null 和 undefined 的几种方法
// 去除对象中所有的 null 和 undefined 的几种方法
function removeNullUndefined(obj) {
// 这里需要注意的是 null == undefined 结果为 true
return Object.fromEntries(Object.entries(obj).filter(([_, v]) => v != null))
}
function removeNullUndefined2(obj) {
return Object.entries(obj).reduce(
(res, [key, value]) => (value == null ? res : (res[key] = value), res),
{}
);
}
function removeNullUndefined3(obj) {
return Object.entries(obj)
.filter((([key, value]) => value != null))
.reduce((res, [key, value]) => ({ ...res, [key]: value}), {})
}
const res1 = removeNullUndefined({
name: null,
age: undefined,
sex: 1
})
const res2 = removeNullUndefined2({
name: null,
age: undefined,
sex: 1,
});
const res3 = removeNullUndefined3({
name: null,
age: undefined,
sex: 1,
});
console.log(res1);
console.log(res2);
console.log(res3)
17 生成一个随机布尔值
// 生成一个随机的 布尔值
// generate a random boolean
function generateRandomBoolean() {
return Math.random() >= 0.5
}
18 指定范围内生成浮点数
// 在指定范围内生成浮点数
// generate a randowm floating point number in given range
function generateFloatInRange(min, max) {
return Math.random() * (max - min) + min
}
const res = generateFloatInRange(10, 100)
console.log(res);
19 生成随机颜色
// 生成随机 16 禁止颜色
// generate randow hex color
function generateRandomHexColor() {
return `#${Math.random().toString(16).slice(2, 8).padEnd(6, "0")}`;
}
const res = generateRandomHexColor()
console.log(res);
20 指定范围生成一个整数
// 根据指定范围生成一个随机整数
// generate a random integer in given range
const randomInteger = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
21 生成随机字符串
// 根据指定字符,生成指定字符串
// generate a randow string from given characters
function randomString(length, chars) {
return Array(length)
.fill("")
.map((v) => chars[Math.floor(Math.random() * chars.length)])
.join('')
}
const resStr = randomString(
10,
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
)
console.log(resStr);
22 生成全为整数的随机数组
// 指定范围生成元素全为整数的数组
// generate an array of random integers in a given range
const randomArrayInRange = (min, max, n) =>
Array.from(
{ length: n },
(v) => Math.floor(Math.random() * (max - min + 1)) + min
);
const res = randomArrayInRange(1, 100, 10);
console.log(res);
23 字符串首字母大写
// 字符串首字母大写1
// capitalize a string
function capitalize(str) {
return `${str.charAt(0).toUpperCase()}${str.slice(1)}`
}
function capitalize2([first, ...rest]) {
// 这里可以直接使用解构字符串
return `${first.toUpperCase()}${rest.join("")}`;
}
const res2 = capitalize("hello world");
console.log(res2);
24 检查路径是否为绝对路径
const isRelativePath = (path) => !/^([a-z]+:)?[\\/]/i.test(path);
25 检查一个字符串是否有重复序列
// 检查一个字符串是否有重复序列
// # Check if a string consists of a repeated character sequence
function consistsRepeatedSubstring(str) {
// indexOf 有两个参数(searchValue, fromIndex)
return `${str}${str}`.indexOf(str, 1) !== str.length;
}
const res = consistsRepeatedSubstring('abc')
const res3 = consistsRepeatedSubstring('aaa')
console.log(res);
console.log(re4);
26 检查一个值是否是函数
// 检查一个值是否为函数
// check if a value is a function
function isFunction(v) {
return [
"[object Function]",
"[object GeneratorFunction]",
"[object AsyncFunction]",
"[object Promise]",
].includes(Object.prototype.toString.call(v))
}
console.log(isFunction(function () {}));
console.log(isFunction(function* () {});
console.log(isFunction(async function () {});
27 组合函数
// 组合函数
function pipe(...fns) {
return (x) => fns.reduce((y, f) => f(y), x)
}
const lowercase = (str) => str.toLowerCase();
const capitalize = (str) => `${str.charAt(0).toUpperCase()}${str.slice(1)}`;
const reverse = (str) => str.split('').reverse().join('');
const fn = pipe(lowercase, capitalize, reverse);
console.log(fn('Hello World'));