节流:事件连续触发时,在一定时间间隔内只执行一次;一般应用在鼠标移动和监听页面的滚动事件中
function throttle(fn, interval, options = { leading: true, trailing: true}) {
// 定义一个变量用来记录事件第一次触发时的时间
// 其实对于第二次执行来说就是第一次执行的结束时间
let lastTime = 0 //初始化为0
let timer = null // 初始化定时器
const { leading, trailing } from options
return function (...args) {
// 记录当前事件触发时的时间
const nowTime = new Date().getTime()
// 如果第一次不进行触发事件就leading设为 false
if(!leading && !lastTime) lastTime = nowTime
// 记录剩余多少时间来触发事件执行,interval是传进来的时间范围
const remainTime = interval - (nowTime - lastTime)
if(remainTime <= 0) {
// 防止过多执行事件,比如末尾需要执行事件,首次不进行触发,则
// 一开始就会添加定时器,当剩余时间到了进来就会执行两次,
if(timer) {
clearTimeout(timer)
timer = null
}
// 进来表示到了执行时间了,执行事件,并保存当前事件的执行时间
fn.call(this, ...args)
lastTime = nowTime
// 执行完事件无需在给其添加定时器返回即可
return
}
// 如果最后一次要进行触发事件
if(!timer && trailing) {
timer = setTimeout(() => {
fn.call(this, ...args)
timer = null
// 将lastTime进行初始化
// 这样设置是为了防止定时器执行完以后,不要再去触发剩余时间小余0这一条件
lastTime = !leading? 0 : new Date().getTime()
}, remainTime)
}
}
}
节流操作效果
防抖:事件连续触发时,只执行最后一次触发的事件。
// 防抖操作---比起节流防抖要简单的多
function debounce(fun,delay,leading) {
let timer = null
return function(...args) {
// 首次触发要执行
if(leading && !timer){
fun.apply(this, args)
}
if(timer){
clearTimeout(timer)
timer = null
}
timer = setTimeout(() => {
fun.apply(this, args)
timer = null
}, delay)
}
}