什么是防抖 ?
防抖:单位时间内,频繁触发事件,只执行最后一次
举例:
百度输入框, 输入一个字母下面就会有提示
输入第二个字母下面的提示就会变
而别的浏览器只有在你输入结束之后才出现提示, 这就是做了防抖处理
使用场景:
搜索框搜索输入。只需用户最后一次输入完,再发送请求手机号、邮箱验证输入检测
例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text">
</body>
</html>
<script>
let ipt =document.querySelector('input')
ipt.addEventListener('input' ,e=>{
console.log(e.target.value);
})
</script>
每次只要输入一个字母 就会触发
因为 input 事件会在 用户输入内容时 立即触发。每当用户更改输入框的内容(包括键盘输入、粘贴文本、删除字符等),事件会立即响应并执行相应的回调函数。
缺点:
- 性能消耗:每次输入时都会触发请求,特别是当用户快速输入多个字符时,会导致服务器频繁响应大量的请求,造成性能浪费和不必要的网络请求。
- 过多的请求:如果用户快速输入或删除字符,系统会发送许多请求。即使用户最终并没有提交搜索,这些请求依然会被发送并处理,浪费服务器资源。
- 用户体验差:如果搜索建议在每个字符输入后都迅速更新,可能会造成界面频繁刷新,导致闪烁或卡顿,影响用户体验。
防抖实现的方式
手写防抖函数
逻辑:
// 手写防抖函数
// 核心是利用 setTimeout定时器米实现
// 1.声明定时器
// 2.每次鼠标移动(事件触发)的时候都要先判断是否有定时器,如果有先清除定时器
// 3.如果没有定时器,则开启定时器,存入到定时器变最里面
// 4、定时器里面写函数调用
1 使用闭包函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text">
</body>
</html>
<script>
//模板:
function debounce(fn, delay){
let timer=null//闭包变量
return function(){
clearTimeout(timer)
timer = setTimeout(() => {
fn()
}, delay);//返回值是一个定时器ID
}
//连续点击相当于fn想要被调用多次, 但是只有时间 >delay的时候fn才会被调用
//如果时间间隔是1秒, 在输入一秒之后应该结束, 但是在一秒之后, 又输入了一次, 说明又需要调用fn,所以需要把timer清空, 不然timer可能是重复的
}
let ipt=document.querySelector('input')
let timer=null
function handle(){
console.log('发送请求'+ipt.value);
}
let debounceInput=debounce(handle,1000)
ipt.addEventListener('input',debounceInput)
</script>
2 不使用闭包函数
let ipt =document.querySelector('input')
let timer=null
ipt.addEventListener('input' ,e=>{
clearTimeout(timer)
timer=setTimeout(()=>{
console.log(e.target.value);
},500)
})
lodash
https://www.lodashjs.com/
或者用国内的cdn
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box{
border: 1px solid black;
width: 300px;
height: 300px;
}
</style>
<script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
</head>
<body>
<input type="text">
<div class="box"></div>
</body>
</html>
<script>
const box=document.querySelector('.box')
let i=1
function mouseMove(){
box.innerHTML=i++
}
// box.addEventListener('mousemove',mouseMove)
box.addEventListener('mousemove',_.debounce(mouseMove,500))
// _.debounce(要防抖的函数名, 500-等待时间)
//返回一个debounced(防抖动)函数
</script>