以一个搜索为例子
如下代码执行后输入一个字,发现执行了多次
<!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>
<input type="text">
<script>
let inp = document.querySelector("input")
inp.oninput = function(){
console.log(this.value)
}
</script>
<body>
</body>
</html>
可以看到这种现象,是属于事件触发过于频繁,因此,我们前端需要进行防抖,我们只要最后一次的事件。
防抖处理
利用setTimeOut 在一定时间后去获取这个值,即用户输入完成后一段时间在触发执行业务逻辑
<!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>
<input type="text">
<script>
let inp = document.querySelector("input")
let time = null;
inp.oninput = function(){
if(time !== null){
clearTimeout(time)
}
time = setTimeout(()=>{
console.log(this.value);
},500)
console.log(this.value)
}
</script>
<body>
</body>
</html>
可以看到有效的减少console
现在我们的业务代码console和防抖代码杂糅在一起,这是不优雅不利于维护的,我们可以利用闭包来封装防抖函数。
<!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>
<input type="text">
<script>
let inp = document.querySelector("input")
let time = null;
// inp.oninput = function(){
// if(time !== null){
// clearTimeout(time)
// }
// time = setTimeout(()=>{
// console.log(this.value);
// },500)
// }
inp.oninput = debounce(function(){
console.log(this.value)
},500)
// 封装防抖
function debounce(fn,delay){
return function(){
if(time !== null){
clearTimeout()
}
time = setTimeout(()=>{
console.log('this',this); // 这里的this指的是input
fn().call(this) //把fn的this由windows改成input
},delay)
}
}
</script>
<body>
</body>
</html>
## 节流与防抖大致一样,就是逻辑稍微有些不同,
节流作用域控制执行的次数,防抖是执行最后一次。
```html
<!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> body{height: 2000px;}</style>
</head>
<body>
<script>
// 防抖只执行最后一次
//节流控制执行次数
//节流作用控制高频次数,限制流量
window.onscroll = throttle(function(){
console.log('hello world');
},500)
function throttle(fn,delay){
let flag = true
return function(){
if(flag){
setTimeout(()=>{
fn().call(this)
flag = true
},delay)
}
flag = false
}
}
</script>
</body>
</html>
>