防抖与节流
防抖
防抖概念: 用户触发事件过于频繁,只需要处理最后一次事件的操作。
防抖案例: 比如在搜索框搜索查询时,只在用户输入完之后才去服务器查询搜索关键字信息。就运用了防抖。如果不运用防抖,那么用户的每一个输入都会与服务器进行一次交互,严重影响性能,且浪费资源。
<body> <!-- html -->
<input type="text">
<script> /* javascript */
let inp = document.querySelector("input");
inp.oninput = function(){
console.log(this.value);
}
</script>
</body>
![函数属性描述](https://tva1.sinaimg.cn/large/008i3skNly1gvfq6zvg4rj61400tm77902.jpg)
利用计时器实现防抖: 我们可以通过 setTimeout 的方式,在一定的时间间隔内,只处理多次事件触发中的最后一次事件。
let inp = document.querySelector("input");
let t = null; // 在全局初始化计时器对象为null
inp.oninput = function(){
if(t !== null){ // 当计时器不为null时,说明在一定时间内有事件触发了,又
clearTimeout(t); // 进入了一次事件触发,那么就清掉前面的计时器
}
t = setTimeout(()=>{ // 新建新的计时器重新计时
console.log(this.value);
},500)
}
![函数属性描述](https://tva1.sinaimg.cn/large/008i3skNly1gvfqis49c5j61400kwgn602.jpg)
上述方法的问题: ①有全局变量,使代码维护变得困难②业务代码逻辑和防抖的实现逻辑混在一起。
![函数属性描述](https://tva1.sinaimg.cn/large/008i3skNly1gvfqq6nthpj61ee0jgtc602.jpg)
解决方法: 利用闭包封装一个防抖的方法
<script>
let inp = document.querySelector("input");
inp.oninput = debounce(function () {
console.log(this.value);
}, 500)
function debounce(fun, delay) { // 封装防抖函数
let t = null;
return function () {
if (t !== null) {
clearTimeout(t);
}
t = setTimeout(() => {
fun.call(this);
}, delay)
};
}
</script>
代码分析:
![函数属性描述](https://tva1.sinaimg.cn/large/008i3skNly1gvfrce1qepj61gc0suqbb02.jpg)
节流
节流概念: 非常频繁的事件不断触发时,控制其处理次数即频率。
节流案例: 比如在网页上滑动滚轮事件,其实是一个触发非常频繁的事件。如果该操作是更复杂的逻辑请求事件同样也会很浪费资源,影响性能。
<script>
window.onscroll = function(){
console.log("hello world");
}
</script>
![](https://tva1.sinaimg.cn/large/008i3skNly1gvftggdu5pg613s0nywyx02.gif)
利用计时器实现节流: 我们可以通过 setTimeout 的方式,在一定的时间间隔内,只执行一次事件触发操作。
<script>
let flag = true;
window.onscroll = function(){
if(flag){
setTimeout(()=>{
console.log("hello world");
flag = true;
},500)
}
flag = false;
}
</script>
![函数属性描述](https://tva1.sinaimg.cn/large/008i3skNly1gvftu866u2g613u0ny4qp02.gif)
完善: 同样单纯利用计时器实现节流也会有防抖中的问题,同样可用用闭包来封装节流函数
<script>
window.onscroll = throttle(function(){
console.log("hello world");
},500)
function throttle(fun,delay){
let flag = true;
return function(){
if(flag){
setTimeout(()=>{
fun.call(this);
flag = true;
},delay)
}
flag = false;
}
}
</script>