一. 封装代码(防抖)
let btn = document.getElementById('btn');
function submit() {
console.log('submit1234444')
}
function debounce(fn,delayTime,trggleNow = false) {
let t = null;
return function() {
if(t) {
clearTimeout(t)
}
if(trggleNow) {
let firstTriggle = !t;
if(firstTriggle) {
fn.apply(this)
t = setTimeout(() => {
t = null
},delayTime)
} else {
t = setTimeout(() => {
fn.apply(this)
t = null
},delayTime)
}
} else {
t = setTimeout(() => {
fn.apply(this);
},delayTime)
}
}
}
btn.addEventListener('click',debounce(submit,1000,true))
封装思路:
- setTimout可以将短时间内点击,汇聚成一次点击;
- 防抖函数的调用,其实质是调用return function()这个函数,根据谁调用,this指向谁的原则,所以需要用apply改变this指向。
- t= null,用到了闭包,在代码调中做初始化使用,好处是在函数外部可以使用并改变t这个变量值。
- 有些场景,比如接口请求中,我们可能需要第一次立即执行,所以给了一个参数判断是否需要立即执行,满足多场景使用
- clearTimeOut(t),用于清除之前的计数器,但是不意味着清除后t就变成了null
二. 封装代码(节流)
function throttle(fn,delayTime) {
let pre = 0;
return function() {
let cur = Date.now();
if(cur - pre > delayTime) {
fn.apply(this)
pre = cur
}
}
}
封装思路:
- 基本原理和防抖类似。不同的是,采用时间的比较代替了setTimeout;
- 节流函数在规定的时间范围会完成首次执行,且只有一次操作。
- 和防抖函数对比:执行调用的依赖不同,防抖是从用户操作层面,比如点击按钮,只会执行最后一次的点击,而节流是从时间层面,在规定的延迟时间内,无论用户怎么操作,都会执行一次。