/**
* 防抖:不管事件触发频率多高,一定在事件触发 n 秒后才执行,如果在一个事件执行的 n秒内又触发了这个事件,就以新的事件的时间为准
* @callback fn -被调用的函数
* @param {number} [wait = 300] -定时器时间
* @param {boolean} [immediate = false] -是否要立即执行一次
*/
export function debounce(fn, wait = 300, immediate = false) {
// 参数验证
if (typeof fn != ‘function‘)
throw Error("第一个参数必须是函数!");
if (typeof wait != ‘number‘)
throw Error("第二个参数必须是数字!");
if (typeof immediate != ‘boolean‘)
throw Error("第三个参数必须是布尔值!");
let timer = null;
// 返回一个函数
return function() {
// 是否要立即执行一次
if (!timer && immediate)
fn.apply(this, arguments);
// 每次触发事件时都取消之前的定时器
clearTimeout(timer);
// setTimeout 中使用箭头函数,就是让 this指向 返回的该闭包函数,而不是 debounce函数 的调用者
timer = setTimeout(() => {
fn.apply(this, arguments)
}, wait)
}
}
window.addEventListener(‘resize‘, debounce(function() {}, 200));
mehtod: debounce(function() {}, 200)
第一次事件肯定触发,最后一次不会触发(比如说监听 onmousemove,则鼠标停止移动时,立即停止触发事件)
function throttle(fn, wait) {
// 记录上一次执行的时间戳
let previous = 0;
return function(...args) {
// 当前的时间戳,然后减去之前的时间戳,大于设置的时间间隔,就执行函数,否则不执行
if(Date.now() - previous > wait) {
// 更新上一次的时间戳为当前时间戳
previous = Date.now();
fn.apply(this, args);
}
}
}
第一次事件不会触发(fn是放在 setTimeout中执行的,所以第一次触发事件至少等待 wait 毫秒之后才执行),最后一次一定触发
function throttle(fn, wait) {
// 设置一个定时器
let timer = null;
return function(...args) {
// 判断如果定时器不存在就执行,存在则不执行
if(!timer) {
// 设置下一个定时器
timer = setTimeout(() => {
// 然后执行函数,清空定时器
timer = null;
fn.apply(this, args)
}, wait)
}
}
}
两者结合可以实现,第一次事件会触发,最后一次事件也会触发
/**
* 节流: 不管事件触发频率有多高,只在单位时间内执行一次
* 第一次事件和最后一次事件都触发
* @callback fn -被调用的函数
* @param {number} [wait = 300] -定时器时间
*/
export function throttle(fn, wait = 300) {
// 参数验证
if (typeof fn != ‘function‘)
throw Error("第一个参数必须是函数!");
if (typeof wait != ‘number‘)
throw Error("第二个参数必须是数字!");
// 设置一个定时器
let timer = null;
// 记录上一次执行的时间戳
let previous = 0;
return function() {
// 当前的时间戳,然后减去之前的时间戳,大于设置的时间间隔
if (Date.now() - previous > wait) {
clearTimeout(timer)
timer = null;
// 更新上一次的时间戳为当前时间戳
previous = Date.now();
fn.apply(this, arguments);
} else if (!timer) {
// 设置下一个定时器
timer = setTimeout(() => {
timer = null;
fn.apply(this, arguments);
}, wait)
}
}
}
使用方法和防抖一样
原文:https://www.cnblogs.com/landuo629/p/14305945.html