性能优化:手写防抖和节流以及二者的区别
程序员文章站
2024-01-27 17:05:22
...
防抖(debounce)
防抖(debounce):限制事件被频繁触发。(涉及定时器和闭包)
触发事件时,在一定时间内,若没有再次触发事件,则事件处理函数在时间到达时执行一次;
若在一定时间内,又触发事件,则清除上一次的计时,重新开始计时,直到时间到了再执行函数。
应用:输入框校验,百度搜索出现提示文字功能等
场景:监听输入框,一旦文字变化,即触发keyup事件,则触发change事件,打印出输入框的内容。
防抖效果:用户输入结束或暂停时,才触发change事件。
<input type="text" id="input">
const input = document.getElementById('input')
function change(){
console.log(input.value)
}
input.addEventListener('keyup', change)
结果:在输入时,输入框的内容高频被打印
手写防抖
const input = document.getElementById('input');
function change(){
console.log("this:"+this);
console.log(input.value);
}
// input.addEventListener('keyup', change)
// 手写防抖
function debounce(fn, delay){
// 声明变量来保存计时,让其作为局部变量保存在内存中,且不被随意访问,借助闭包来实现
let timer = null
// 通过return的函数可以来间接访问timer
return function() {
// 如果时间期限还没到又触发了,则清除上一个定时器,重新计算时间
if(timer){
clearTimeout(timer)
}
timer = setTimeout(() => {
// apply函数会执行fn函数,并改变this指向,此时this:谁调用就指向谁 -> 这里为input
fn.apply(this, arguments)
// 执行完后,清空定时器
timer = null
}, delay)
// 也可以简单来:timer = setTimeout(fn, delay),但此时this指向window
}
}
// 运用防抖
input.addEventListener('keyup', debounce(change, 500))
防抖效果:延迟500毫秒后执行,执行的是最近一次触发的事件处理函数。
节流(throttle)
节流(throttle):限制事件被频繁触发。不管怎么触发,在一定时间内,只执行一次。
应用:获取拖拽盒子位置、scroll滚动条等位置。
场景:拖拽一个元素,随时获取该元素被拖拽的位置。
<div id="div" draggable="true">拖拽盒子</div>
const div = document.getElementById('div')
div.addEventListener('drag', function(e) {
console.log(e.offsetX, e.offsetY)
})
效果:事件会频繁触发,容易导致卡顿。
手写节流
const div = document.getElementById('div')
// div.addEventListener('drag', function(e) {
// console.log(e.offsetX, e.offsetY)
// })
// 手写节流
function throttle(fn, delay) {
let timer = null
return function () {
// 每次触发事件时,如果当前有等待执行的函数,则直接return
if(timer){
return
}
timer = setTimeout(() => {
fn.apply(this, arguments)
// 执行完之后,清空定时器
timer = null
}, delay)
}
}
// 运用节流
div.addEventListener('drag', throttle(function(e) {
console.log(e.offsetX, e.offsetY)
}, 500))
节流效果:不管触发几次事件,事件处理函数在500毫秒内只会执行一次,执行的是该时间内第一次触发的事件处理函数。
防抖和节流的区别
防抖是将一定时间内的多次执行变成最后一次执行(需要重新计算时间),
而节流是将每隔一段时间的多次执行变成一次执行(不重新计时)。
上一篇: 接入钉钉API发送企业消息
推荐阅读