前言:
最近在面试中经常遇到一些面试官要求手写防抖,写出来还要在上面加一点功能。趁着空闲时间赶紧总结了一下几种写法,希望能够帮助小伙伴们在求职或者在工作中能用上~
防抖写法:
基本版(绑定this+传参)
要求: 当触发一个事件时,延迟 n 秒后执行相应的操作。如果在这 n 秒内再次触发该事件,会以最新的触发时间为准,重新计时 n 秒后执行操作。换句话说,只有在触发事件后的 n 秒内没有再次触发事件,才会执行操作。
/**
* 防抖
* @param {Function} fn 添加防抖的事件
* @param {Number} delay 延迟毫秒
*/
function debounce(fn, delay){
let timer;
return function() {
let context = this;
let args = arguments;
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(context, args)
},delay)
}
}
//测试代码,可以直接贴在控制台运行
function task(){
console.log('run task')
}
const debounceTask=debounce(task,1000)
window.addEventListener('scroll',debounceTask);
立即执行版
要求: 无需等待事件停止触发后才执行操作,而是在触发事件后立即执行操作,然后在停止触发 n 秒后才能重新触发执行。
/**
* 防抖(立即执行版)
* @param {Function} fn 添加防抖的事件
* @param {Number} delay 延迟毫秒
*/
function debounce(fn,wait){
let timerId = null;
let flag = true;
return function(){
clearTimeout(timerId);
if(flag){
fn.apply(this,arguments);
flag = false
}
timerId = setTimeout(() => {
flag = true
},wait)
}
}
//测试代码,可以直接贴在控制台运行
function task(){
console.log('run task')
}
const debounceTask=debounce(task,1000,true)
window.addEventListener('scroll',debounceTask);
立即执行+取消防抖版
要求: 假设防抖的时间间隔为 10 秒,且 immediate 为 true。这意味着只有等待 10 秒后才能重新触发事件。现在添加一个取消等待的功能,一旦执行该功能,防抖将被取消,这样就可以立即再次触发事件并执行操作。
/**
* 防抖(立即执行+取消防抖版)
* @param {Function} func 添加防抖的事件
* @param {Number} wait 延迟毫秒
* @param {Boolean} immediate 是否是立刻执行
*/
function debounce(func, wait, immediate) {
let timeout;
let debounced = function () {
let context = this;
let args = arguments;
if (timeout) clearTimeout(timeout);
if (immediate) {
let canDoNow = !timeout;
timeout = setTimeout(function () {
timeout = null;
}, wait);
if (canDoNow) func.apply(context, args);
} else {
timeout = setTimeout(function () {
func.apply(context, args);
}, wait);
}
};
// 取消函数
debounced.cancel = function () {
clearTimeout(timeout);
timeout = null;
};
return debounced;
}
如果有其他小伙伴还碰到其他的防抖写法,可以在评论区说交流一下,共同进步呀~