这是我参与2022首次更文挑战的第1天,活动详情查看:2022首次更文挑战
工作场景
有一个这样的需求,就是我们写一个类似于百度搜索这样的功能,我们输入一个关键字,下面会自动给我们返回带有关键字的这样一个需求,我们该怎么实现呢?
先看代码
<!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>
<style>
.box {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
</style>
</head>
<body>
<div class="box">
<div>
<h1>百度sou索</h1>
<input type="text" id="inputBox">
</div>
</div>
<script>
var inputBox = document.getElementById('inputBox')
inputBox.addEventListener('input', () => {
console.log('输入了内容并发送请求');
})
</script>
</body>
</html>
浏览器表现如下
思考一
我们在搜索框多次输入字段,每输入一个就会发送一个请求,这样非常的频繁请求,服务器的压力非常的大。这是非常不可取的,而且我们也许只是想获取我们想要的信息而已。
我只想知道123456,不想知道1是什么,12是什么等等
所以我们设置一个函数,就是想让用户输入完毕的时候,才发送请求
然后我们把代码写成下面这样了
var inputBox = document.getElementById('inputBox')
function shake(fn) { //接收一个参数fn
}
inputBox.addEventListener('input', shake(() => {
console.log('输入了内容并发送请求');
}))
我们将那个匿名函数作为一个参数传入到shake函数中,就是转变为,每次输入就触发一次这个函数,这样相比于上面好理解多了。
虽然它看起来好理解,但是总感觉好奇怪的,因为addEventListener第二个参数应该是一个函数,但是这里的值是由shake决定的,而且这个shake是返回的一个结果,如果它返回的不是函数,那就是非常的不对了,所以我们就改写成这样,让他返回一个函数
var inputBox = document.getElementById('inputBox')
function shake(fn) { //接收一个参数fn
return function() {
console.log('shake 这个函数执行了');
fn()
}
}
inputBox.addEventListener('input', shake(() => {
console.log('发送搜索框');
}))
然后到页面上看一下
但是我们多次输入还是一样一直打印,然后我们可以给个定时器,让他等一下再去返回,看看效果如何。
var inputBox = document.getElementById('inputBox')
function shake(fn) { //接收一个参数fn
return function() {
setTimeout(() => {
console.log('shake 这个函数执行了');
fn()
}, 500)
}
}
inputBox.addEventListener('input', shake(() => {
console.log('发送搜索框');
}))
然后我们再去浏览器控制台看一下
虽然他是延迟了执行,但是还是执行了多次,也就是我们无论触发多少次,最后到达时间还是执行一样的次数
为什么会这样呢?
原来是它触发了两次,只不过是延后执行,那么我们想要的效果是让他只返回一次,那么我们可以想,就是在进入之前,把上一个定时器销毁掉,只执行最后一个定时器,然后代码如下
var inputBox = document.getElementById('inputBox')
function shake(fn) { //接收一个参数fn
let timer = null;
return function() {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
console.log('shake函数执行了');
fn()
}, 500)
}
}
inputBox.addEventListener('input', shake(() => {
console.log('发送搜索框');
}))
也就是说,我先声明一个空的定时器,然后每次执行的时候,先判断定时器有没有,如果有,就进入清理定时器那一步,如果没有,就进行下一步,所以,我们看浏览器怎么返回
虽然我执行了很多次,打了好几个1,但是,只给我返回一次
所以,以上就是实现防抖的重要技术要点了
🤞作者小三是刚刚毕业不久全栈工程师,写的技术文章基本上是学习过程中笔记整理而来,大家看了之后如果喜欢可以给小弟点点赞哦。
🎁 粉丝福利:学习资料、简历模板统统都有点击领取