DOM操作(onresize, onscroll….等等操作),有的的时候会多次触发,为了减少操作,从而有了节流的概念。
函数节流的思想很简单:在每次出发的时候我们就开一个定时器,将DOM操作延迟,然后在下一次事件触发的时候,我们把这个定时器关掉,我们开关定时器,一直到一定的时机在触发事件。
javasscript 高级程序设计中的方法
function throttle (fn, context) {
fn.tId && clearTimeout(fn.tId)
fn.tId = setTimeout((() => {
fn.call(context)
}, 500)
}
// 很简单进入函数则清除定时器,重新创建一个定时器,然后把定时器id设置为fn,做缓存,等到用户事件不触发,500毫秒以后执行事件,并通过call修改执行this指向
网上流行的方法
function throttle (fn, delay) {
var timer = null;
return function () {
var context = this,
args = arguments;
clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(context, args)
}, delay)
}
}
函数防抖
函数节流是一个很好用的方法,但是在某些场景下,我并不希望每次都是要事件结束后等待delay的时间后才执行回调,但是又希望减少操作,那么我们可以按照之前的思想,开关定时器即可
//第一种 我们根据时间触发函数
function throttle(fn , duration ,delay ){
var timer = null,
// 记录下开始执行函数的时间
begin = new Date();
return function () {
var context = this,
args = arguments;
// 记录下当前时间
current = new Date();
// 函数节流里的思路
clearTimeout(timer)
// 记录下的两个时间相减再与duration进行比较
if (current-begin >= duration) {
fn.apply(context , args)
begin = current;
} else {
timer = setTimeout(() => {
fn.apply(context , args)
}, delay)
}
}
}
//第二种 根据触发的次数触发函数
function throttle(fn, maxLength){
//新建计数器,最大等待次数
var count = 0
maxLength = maxLength || 300;
// 返回一个函数,实现作用域,缓存count的状态和maxLength
return function () {
var context = this,
args = arguments,
// 不满足条件 则不继续执行方法
count++;
if(count < maxLength) return '';
// 当到达需要触发的时机以后我们触发函数,并将计数器归零
count = 0
fn.apply(context , args)
}
}