节流
如果给元素一个
scroll
事件,然后你开始滚动滚轮,假如它一秒钟执行50次,而你只想它每秒最多执行1次,这就是节流。
案例
1、不用写闭包的版本
function throttle(doc, eventName, fn, time = 1000) {
let timer
doc.addEventListener(eventName, function(){
if(timer) return
fn.call(this)
timer = setTimeout(() => {
clearTimeout(timer)
timer = null
},time)
})
}
//调用
throttle(document, 'scroll', function() {
console.log(this)
})
2、写闭包的版本
//传入两个值,一个是要执行的方法,一个是执行周期
function throttle(fn,time = 1000) {
//先声明一个计时器
let timer
//返回一个方法(闭包)
return function() {
//如果计时器存在则不执行
if(timer) return
//如果计时器不存在则执行
//此this到时候会变成调用这个方法的元素
fn.call(this)
//设置一个一定时间自身清理的计时器
timer = setTimeout(() => {
clearTimeout(timer)
timer = null
},time)
}
}
//调用函数创建一个新的带有节流的函数
let fn = throttle(function () {
console.log(this)
})
//设置事件
document.addEventListener('scroll',fn)
总的来说就是有计时器的时候不执行,没有计时器后就执行并创建一个新的会自杀的计时器。
防抖
给搜素框一个keyup事件,onkeyup就直接去搜索,现在想让用户输入完成后再进行搜索,也就是在用户频繁输入的时候不执行keyup事件,这就是防抖
案例
1、不用写闭包的版本
function debounce(doc, eventName, fn, time = 1000) {
let timer
doc.addEventListener(eventName,function () {
//如果计时器存在,则删掉
if(timer) clearTimeout(timer)
//每一次都重新创建计时器
timer = setTimeout(() => {
fn.call(this)
}, time)
})
}
//调用
debounce(document,'scroll',function() {
console.log(this)
})
2、写闭包的版本
function debounce(fn, time = 1000) {
let timer
return function() {
if(timer) clearTimeout(timer)
timer = setTimeout(() => {
fn.call(this)
}, time)
}
}
//调用
const fn = debounce(function() {
console.log(this)
})
document.addEventListener('scroll',fn)
防抖就是一直刷新带过一段时间后执行的计时器,如果用户手停了,就执行。不然一直删除一直执行,计时器就不会执行。