简单实用的方法能够大幅度提高我们日常开发的效率,废话不多说。
1、debounce防抖函数
// fn 是回调函数, delay是间隔时间
function debounce(fn, delay) {
let cd = 0;
return function (...args) {
if (cd) {
clearTimeout(cd);
}
cd = window.setTimeout(
() => fn.apply(this, args),
delay
);
}
}
2、throttle节流函数
// fn 是回调函数, wait是间隔时间
function throttle(fn, wait = 50) {
let prev = 0;
return function(...args) {
let now = +new Date();
if (now - prev > wait) {
prev = now;
fn.apply(this, args)
}
}
}
图中所示,一秒钟执行了一次
3、unique数组去重
日常开发中会用到数组去重,有时还需要对数组中的对象某个键去重,那么你就可以用下面这个方法
function isArray(arr) {
return Object.prototype.toString.call(arr) === '[object Array]';
}
function unique(arr, keyGetter) {
if (!isArray(arr)) {
return;
}
if (keyGetter) {
const map = {};
const keyCreator = typeof keyGetter === 'string' ? (obj) => obj[keyGetter] : keyGetter;
return arr.filter(item => {
const key = keyCreator(item);
if (key in map) {
return false;
}
map[key] = 1;
return true;
});
} else {
return [...new Set(list)];
}
}
const list = ["1998", "1997", "2000", "1999", "1996", "2000", "2001", "1998", "1996"];
unique(list);
const arr = [{"code": "YY", name: "liu"}, {"code": "ZZ", name: "zhang"}, {"code": "ZZ", name: "chen"}];
unique(arr, 'code');
4、Cookie的写入、读取、删除
function setCookie(key, value, expire, path = '/', domain) {
const item = [`${key}=${value}`];
const _expire = () => {
const date = new Date();
date.setTime(expire);
return date;
}
if (expire) {
item.push(`expire=${_expire}`)
}
item.push(path);
item.push(domain);
document.cookie = item.join('; ');
}
function getCookie(key) {
if (!key) {
return;
}
const reg = new RegExp(`^\\s*${key}`, 'i');
const cookies = document.cookie.split(';');
for (const cookie of cookies) {
const [key, value] = cookie.split('=');
if (reg.test(key)) {
return value || '';
}
}
}
/**
* 将存入的cookie设置过期即可删除cookie
*/
function delCookie(key, path, domain) {
if (getCookie(key)) {
const date = new Date();
date.setTime(date.getTime() - 1 * 24 * 60 * 60 * 1000);
setCookie(name, '', date, path, domain);
}
}
5、动态加载js
function loadJs(src, async) {
return new Promise((resolve, reject) => {
const s = document.createElement('script');
s.src = src;
if (async) {
s.async = true;
s.defer = true;
}
s.onload = function() {
resolve(true);
}
s.onerror = reject();
doucment.head.appenChild(s);
});
}
6、回到顶部
function toTop() {
document.body.scrollIntoView();
}
haha~, so easy!
7、图片的懒加载
function lazyLoad(images) {
// 实例化IntersectionObserver对象
const ob = new IntersectionObserver(entries => {
entries.forEach(entry => {
// 进入可视区域
if (entry.intersectionRatio > 0) {
// 此时将图片节点绑定的data-src赋值给图片节点的src
entry.target.src = entry.target.dataset.src;
ob.unobserve(entry.target);
}
})
})
images.forEach(img => ob.observe(img));
}
IntersectionObserver接口(从属于Intersection Observer API)为开发者提供了一种可以异步监听目标元素与其祖先或视窗(viewport)交叉状态的手段。祖先元素与视窗(viewport)被称为根(root), 兼容性方面的除了IE浏览器,其他浏览器大部分都支持的。
8、判断数据类型
// 用到的方法就是Object.prototype.toString();
function isArray(arr) {
return Object.prototype.toString.call(arr) === '[object Array]'
}
function isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]'
}
// 还有别的其他的类型如下等等,就不一一举例了
// '[object String]'、'[object Number]'、'[object Boolean]'、'[object Undefined]'、'[object Null]'
9、深拷贝
老生常谈,直接上代码
function deepClone(obj) {
if (typeof obj !== 'object' || obj === null) {
return obj;
}
let res = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
res[key] = deepClone(obj[key])
}
}
return res;
}
10、日期格式化
日期格式化通常开发都会碰到,所以也把它拉过来了。
/*
* date, 传入日期对象
* format, 传入指定日期的格式
*/
function formatDate(date, format = 'YYYY-MM-DD HH:mm:ss') {
// 这里将传入的日期对象分别转化为 年、月、日、时、分、秒
const cfg = {
'YYYY': date.getFullYear(),
'MM': date.getMonth() + 1,
'DD': date.getDate(),
'HH': date.getHours(),
'mm': date.getMinutes(),
'ss': date.getSeconds()
};
for (const key in cfg) {
// 直接循环将传入的格式替换为对应的值
format = format.replace(key, cfg[key]);
}
return format;
}