函数防抖
当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行,如果设定时间到来之前,又触发了事件,就重新开始计算延迟。也就是说当一直触发这个函数,且每次触发函数的间隔小于既定时间,那么防抖的情况下只会执行一次。
function antiShake(fn, wait) {
var timeout = null; //定义一个定时器
return function() {
if(timeout !== null) {
clearTimeout(timeout); //清除这个定时器
}
timeout = setTimeout(fn, wait);
}
}
// 处理函数
function handle() {
console.log("Hello, World");
}
// 点击事件
window.addEventListener('click', antiShake(handle, 1000));
当用户快速的持续点击屏幕的时候触发事件但是下一次点击的时候我清除之前触发的事件,也就是说当再特定的时间间隔一直触发点击事件其实只有最后停下的那一次可以完成事件,可以避免频繁的调用函数造成的卡顿,有效减少了性能的损耗
函数节流
当持续触发事件时,保证在规定时间内只调用一次事件处理函数,减少事件执行的频率。意思就是说,假设一个用户一直触发这个函数,且每次触发小于既定值,函数节流会每隔这个时间调用一次
实现函数节流我们主要有两种方法:时间戳和定时器
例如
function throttle(func, delay) {
var prev = Date.now();
return function() {
var context = this; //获取当前this的指向
var args = arguments;
var now = Date.now();
if (now - prev >= delay) {
func.apply(context, args);//绑定this指向为触发事件的元素
prev = Date.now();
}
}
}
function test(a) {
console.log("Hello, World");
}
document.addEventListener('click', test(handle, 1000));
获取第一次时间戳 当第二次获取时间戳的时候 比第一大于或者等于指定时间的时候在执行回调函数,并改变第一次的时间戳。
这个节流函数利用时间戳让第一次点击事件执行一次回调函数,此后每隔1000ms执行一次,在小于1000ms这段时间内的滚动是不执行的
利用定时器的方法,
再举一个定时器的例子:
function throttle(func, delay) {
var timer = null;;
return function() {
var context = this;
var args = arguments;
if (!timer) {
timer = setTimeout(function() {
func.apply(context, args);
clearTimeout(timer);
timer = null;
}, delay);
}
}
}
function handle() {
console.log("Hello, World");
}
document.addEventListener('click', throttle(handle, 1000));
当触发事件的时候,需要判断定时器是否存在 不存在的时候添加定时器 并延迟指定时间后执行函数 在清除定时器 。也就是说当第一次触发事件,到达规定时间再执行这个函数,执行之后马上清除定时器,开始新的循环,
用一句话总结防抖和节流的区别:防抖是将多次执行变为最后一次执行,节流是将多次执行变为每隔一段时间执行