1. 理解
防抖就是在事件触发以后,在规定的时间内只会执行一次,如果在规定的时间之内,重新触发了这个事件,则会进行重新计时 ( 一般用于搜索框内输入字段,下面给出后台返回的提示)
简单来说就像是打游戏,防抖函数的执行就像是在回城,如果在回城时被打断,再次回城的话,需要重新计时
2. 手写一个防抖函数
fn 代表要执行的函数,delay 代表时间段
function debounce(fn,delay){
let timer = null
return function(){
if(timer !== null) {
clearTimeout(timer)
}
timer = setTimeout(()=>{
// 对要调用的函数的this进行绑定,二选一
// 第一种方式
// fn.apply(this,arguments)
// arguments 可以用来传递值
// 第二种方式 还可以使用 fn.call(this) 来绑定this
fn.call(this)
},delay)
}
}
3. 实际应用
输入框内的值发生变化时,在规定的时间内只会执行一次fun函数,如果在规定的时间之内,重新触发了这个事件(值有了新的变化),则会进行重新计时
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>防抖练手</title>
</head>
<body>
<h1>测试防抖</h1>
<input type="text" id="input">
<script>
// 获取元素
let inputValue = document.getElementById('input')
// 添加事件
inputValue.addEventListener('keyup', debounce(fun, 2000))
//定义方法即要做的事情
function fun(e) {
// 获取arguments传过来的input输入框的值(e.target.value)
console.log(this.value)
}
//定义事件触发要执行的方法,两个参数分别是传入的要做的事情和定时器的毫秒数
function debounce(fn, delay) {
//定义一个变量作为等会清除对象
var timer = null
//这里用到了闭包,一个函数里面return另一个函数,变量相互签引导致垃圾回收机制不会销毁timer变量
return function () {
//在这里一定要清除前面的定时器,然后创建一个新的定时器
if (timer !== null) {
clearTimeout(timer)
}
//最后这个定时器只会执行一次也就是事件触发完成之后延迟500毫秒再触发(这里的变量赋值是跟定时器建立连接,进行地址赋值,一定要重新赋值给timer
timer = setTimeout( () =>{
// 绑定this
// arguments 可以用来传递值,可以在函数中获取
fn.apply(this,arguments)
}, delay)
}
}
//给浏览器添加监听事件resize
// window.addEventListener('resize', debounce(fun, 2000));
</script>
</body>
</html>