提示:
本文为JavaScript栏目:JavaScript高级学习:事件的防抖和节流03——详解节流
防抖
防抖的思路
其次是第二种思路。
如果短时间内大量触发同一事件,那么在函数执行一次之后,该函数在指定的时间期限内不再工作,直至过了这段时间才重新生效。
简单来说就是给技能加一个冷却时间,事件触发后开始冷却,冷却时间内不能再触发。
初步实现
节流实现的关键在于时间戳的获取和定时器。
我们在时间第一次执行的时候设置一个开始时间(旧时间),那么在后续触发事件时,需要获取旧时间,和现在的时间,计算是否处于冷却时间内。
这样基本就实现了节流。
既然前面都提到了获取时间,那实现的关键就在于获取时间戳。
<script>
let app = document.getElementById("app");
function fun(ev) {
app.innerHTML = parseInt(app.innerHTML) + 1;
}
function throttle(fun, delay) {
let old = 0; //用于设置第一次执行的时候的开始时间(旧时间)
return function() {
let args = arguments;
const now = Date.now(); //获取现在时间
if (now - old > delay) { //判断是否处于冷却中
fun.apply(this, args);
old = now;
}
}
}
app.onmousemove = throttle(fun, 1000)
</script>
效果:
技能二段伤害
但是我们大多时候还要在整个事件的计时结束时,再一次触发事件,以表示冷却完成或计时结束。
姑且理解成技能二段伤害。
<script>
let app = document.getElementById("app");
function counteAddNum(ev) {
app.innerHTML = parseInt(app.innerHTML) + 1;
}
function throttle(fun, delay) {
let old = 0,//记录旧时间戳
timmer;//闭包返回定时器
return function () {
let that = this;/*解决指针指向问题*/
let args = arguments; /*解决event时间问题*/
let now = Date.now(); /*获取现在的时间戳*/
if (now - old > delay) { /*判断冷却是是否结束*/
if (timmer) { /*清楚正在运行的定时器*/
clearTimeout(timmer);
timmer = null;
};
fun.apply(this, arguments);//执行事件
old = now;//记录时间戳
}
if (!timmer) {/*创建节流的定时器,进入冷却时间*/
timmer = setTimeout(function () {
// 冷却时间结束后,再一次执行
old = Date.now();//获取时间戳,并记录时间戳
fun.apply(that, args);/*执行方法*/
timmer = null;/*删除定时器*/
}, delay);
}
}
}
app.onmousemove = throttle(counteAddNum, 1000)
</script>
这里基本就实现了防抖,下定义:
防抖的含义就是让事件处理函数执行后,某个时间期限(如上面的100毫秒)的事件不再触发,。