防抖是前端经常用到的技术,他的功能是其实是延迟函数的执行,只有当等待了一段时间也没有事件触发时,才会真正去执行函数,如果在这期间有事件触发则重新计时,可以理解为王者荣耀中的回城,被打断需要重新回城
下面是防抖函数的简单实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text">
<button id="cancel">取消</button>
<script>
// 防抖函数
function debounce(fn, delay = 0, immediate = false) {
let timer = null
let isInvoke = false
// 检验防抖函数传过来的参数
try {
if (typeof fn !== 'function') throw new error('第一个参数是函数')
if (typeof delay !== 'number' || delay < 0) throw new error('第二个参数为数字并且大于等于0')
if (typeof immediate !== 'boolean') throw new error('第三个参数应为布尔值')
} catch (err) {
console.log(err)
}
const _debounce = function (...args) {
// 取消上一次的定时器
if (timer) clearTimeout(timer)
// 是否立即执行
if (!isInvoke && immediate) {
fn.apply(this, args)
isInvoke = true
} else {
timer = setTimeout(() => {
// apply可以立即调用
fn.apply(this, args)
isInvoke = false
}, delay)
}
}
// 取消按钮
_debounce.cancel = () => {
if (timer) clearTimeout(timer)
timer = null
isInvoke = false
console.log('取消')
}
return _debounce
}
const inputText = document.querySelector('input')
let counter = 0
const inputChange = function () {
console.log(`点击了${++counter}次`)
}
const debounceChange = debounce(inputChange, 3000, false)
inputText.oninput = function () {
debounceChange()
}
const cancel = document.querySelector('#cancel')
cancel.onclick = function () {
debounceChange.cancel()
}
</script>
</body>
</html>