防抖和节流函数目前已经是前端开发场景中非常重要的两个函数,使用场景是非常多的.
防抖
在这一次触发事件的时候,如果间隔小于规定的时间,就清除上一次的延时,然后加上延时,如果一次触发后大于规定的时间没有再触发,则执行。
节约性能, 只触发最后一次
栗子:一般输入会有一定时间间隔才会出现关键词提示
如:在点击按钮之后,经过2秒钟时按钮会触发事件,如果在1.5秒时再次点击按钮,则需要重新计算2秒事件才会触发。
思路和实现
- 事件函数执行, 先创建个定时器
- 把逻辑代码放到定时器中
- 当函数再次触发, 清除定时器
- 创建一个新定时器即可
优化1: 把事件处理函数 – 抽离成独立函数
优化2: 封装一个公共的 – 防抖函数 (最后精华)
节流
连续发生的事件在n秒内只执行一次
也就是说在规定时间内,不管操作多少次,函数只会执行一次。
触发的频率太快, 导致一瞬间触底逻辑执行了
栗子:网页设置有回到顶部按键,但是每次细小滑动也会出现
思路和实现
- 事件函数执行, 先判断有定时器, 则直接return
- 把逻辑代码放到定时器中
- 定时器执行后, 置空定时器变量
- 下载事件函数执行时, 再创建一个新定时器即可
优化1: 把事件处理函数 – 抽离成独立函数
优化2: 封装一个公共的 – 节流函数 (最后精华)
实现
首先定义div标签用于显示页面操作
<div>
id="content"
style="height: 150px; line-height: 150px; text-align: center; background-color: aqua;"
</div>
定义全局变量
let number=0;
let content = document.getElementById('content');
function sum(){
content.innerHTML = number++;
}
防抖方案一:事件响应两秒之后执行
//防抖debounce
//事件响应2秒后执行
function debounce(fun, waittime) {
let timeout;//设置定时器
return function(){
if(timeout)//如果存在定时器则清空
clearTimeout(timeout);
//如果没有定时器则执行下面函数
timeout = setTimeout(function () {
fun.apply(this);//函数调用
},waittime)
}
}
防抖方案二:事件立即响应,两秒之后才能再一次操作
//事件立即响应,2秒之后才能重新点击响应
function debounce(fun,waittime){
let timeout;//设置定时器
return function(){
if(timeout)//如果存在定时器则清空
clearTimeout(timeout);
//类型转换
let timenow = !timeout;
//规定时间之后重新响应
timeout = setTimeout(()=>{
timeout = null;
},waittime);
//没有定时器时,timenow为true,执行函数
if(timenow)
fun.apply(this);
}
}
函数调用
content.onmousemove = debounce(sum, 2000);
节流方案一:设置定时器
// 节流 throttle
// 设置定时器的方法
function throttle(fun,waittime){
let timeout;//设置定时器
return function () {
// 如果没有定时器,则执行下面函数
if(!timeout){
timeout = setTimeout(()=>{
timeout=null;
fun.apply(this);
},waittime)
}
}
}
节流方案二:定义时间戳
//时间戳方法
//通过时间之差判断函数是否执行
function throttle(fun,waittime) {
let prev=0;
return function() {
let now = Date.now();
if(now-prev>waittime){
fun.apply(this);
prev=now;
}
}
}
节流的方案主要是满足在规定时间内即使多次操作,函数也只会执行一次。
函数调用
content.onmousemove = throttle(sum,2000);