目录
第一章 防抖
1.1 防抖(debounce)简介
1.2 应用场景
1.3 实现思路
1.4 手撕防抖代码
第二章 节流
2.1 节流(throttle)简介
2.2 应用场景
2.3 实现思路
2.4 手撕节流代码(方法:时间戳和计时器)
2.5 时间戳与计时器实现的区别
第三章 总结
function debounce(func,delay) {
// 定义一个定时器timer
let timer = null
return function() {
const that = this
const args = arguments
// 防抖核心:每次触发事件计时器都会重新计时
clearTimeout(timer)
timer = setTimeout(()=>{
func.apply(that,args)
},delay)
}
}
未调用防抖函数时:用户每在input输入/删除一个值,都会输出一个值;
调用防抖函数后:用户在input输入/删除一个值delay之后才,会输出一个值
let inputDom = document.getElementById('input')
//func 是执行函数,delay 是事件执行的延迟时间,毫秒
function debounce(func,delay) {
// 定义一个定时器timer
let timer = null
return function() {
const that = this
const args = arguments
// 防抖核心:每次触发事件计时器都会重新计时
clearTimeout(timer)
timer = setTimeout(()=>{
func.apply(that,args)
},delay)
}
}
function handler() {
console.log('this.value',this.value)
}
inputDom.addEventListener('input', debounce(handler, 1000))
// ---------------------节流1:使用时间戳---------------------
//func 是事件处理程序,delay 是事件执行的延迟时间,单位:毫秒
function throttle (func, delay) {
//定义初始时间(开始触发事件的时间)
let start = 0;
return function () {
const that = this
const args = arguments
// 获取当前时间戳
let cur =Date.now()
// 时间间隔大于延迟时间则进入
if (cur - start >= delay) {
//执行事件处理程序
func.apply(that, args);
//更新初始时间
start = cur
}
}
}
// ---------------------节流2:使用定时器---------------------
//func 是事件处理程序,delay 是事件执行的延迟时间,单位:毫秒
function throttle(func, delay){
// 自定义一个定时器
var timer = null;
return function(){
var that = this;
var args = arguments
// timer为null表示可以发送请求了,否则还在请求中,不执行事件
if(!timer){
timer = setTimeout(function(){
//执行事件处理程序
func.call(that, args)
//事件执行完后把定时器清除掉,下次触发事件的时候再设置
timer = null;
}, delay)
}
}
}
未调用节流函数时,每点击一次按钮,都会执行一次函数调用:
const button1Dom = document.getElementById('button1')
button1Dom.addEventListener('click',function(){
console.log("节流:我发送了消息")
})
使用节流函数之后,频繁的点击发送请求,它会在计时器结束之后再发,这段时间内点击发送一次请求之后,不会再发送请求:
const button1Dom = document.getElementById('button1')
// ---------------------节流1:使用时间戳---------------------
//func 是事件处理程序,delay 是事件执行的延迟时间,单位:毫秒
function throttle (func, delay) {
//定义初始时间(开始触发事件的时间)
let start = 0;
return function () {
const that = this
const args = arguments
// 获取当前时间戳
let cur =Date.now()
// 时间间隔大于延迟时间则进入
if (cur - start >= delay) {
//执行事件处理程序
func.apply(that, args);
//更新初始时间
start = cur
}
}
}
// ---------------------节流2:使用定时器---------------------
//func 是事件处理程序,delay 是事件执行的延迟时间,单位:毫秒
// function throttle(func, delay){
// // 自定义一个定时器
// var timer = null;
// return function(){
// var that = this;
// var args = arguments
// // timer为null表示可以发送请求了,否则还在请求中,不执行事件
// if(!timer){
// timer = setTimeout(function(){
// //执行事件处理程序
// func.call(that, args)
// //事件执行完后把定时器清除掉,下次触发事件的时候再设置
// timer = null;
// }, delay)
// }
// }
// }
button1Dom.addEventListener('click',throttle(function(){
console.log("节流:我发送了消息")
},1000))
频繁的点击,降低了发送的频率:
最明显的区别就是在频繁点击的时候,会发现使用时间戳实现的节流会在调用的时候马上执行,而使用计时器实现会在时间段结束时执行