防抖和节流及其底层实现

防抖

单位时间内,频繁触发事件,只执行最后一次。

触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。应用场景:手机号、邮箱验证、搜索框输入。

实现:

利用lodash的 debounced(防抖动)函数。

_.debounce(func, [wait=0], [options=]) 等待时间:[wait=0]单位是多少毫秒,先等待再执行

1
btn.addEventListener('mousemove',_.debounce(fn,500))

其底层是用定时器setTimeout实现的,每次执行前先判断有没有定时器,有则清除定时器。

  1. 声明定时器变量
  2. 每次事件触发前判断有没有存在定时器,有则清除
  3. 开启定时器,存入到定时器变量
  4. 定时器里调用传入的函数
1
2
3
4
5
6
7
8
9
10
11
function debounce(fn,t){
let timer = null
return function(){
if(timer) clearTimeout(timer) //若存在定时器,则删除
timer = setTimeout(function(){
fn()
},t)
}
}

btn.addEventListener('mousemove',debounce(fn,500))

一直移动鼠标,停下来后,等500毫秒才执行。

节流

单位事件内(周期),频繁触发事件,只执行一次。

高频事件触发,但在n秒内只会执行一次。应用场景:window对象的页面尺寸缩放resize、滚动条滚动scroll事件,文字输入,mousemove,射击游戏的mousedown,keydown

例子,射击游戏频繁点击鼠标,为了节流,规定单位事件内点击的n次鼠标只执行一次操作。

实现:

利用lodash的_.throttle(func, [wait=0], [options=]),wait=n毫秒内,只会执行一次操作。

底层实现:

  1. 声明一个定时器变量

  2. 每次事件触发前先判断是否存在定时器,如果有则不开启新定时器

  3. 如果没有定时器则开启定时器,存入定时器变量

    - 定时器里面调用执行的函数
    
    - 定时器里面要把定时器清空
    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function throttle(fn,t){
let timer = null
return function(){
//如果不存在定时器,则创建新定时器
if(!timer){
timer = setTimeout(function(){
fn()
//清空定时器
timer = null
},t)
}
}
}

btn.addEventListener('mousemove',debounce(fn,500))

一直移动鼠标,单位时间500毫秒内无论执行多少次,只执行一次。

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2022-2024 CoffeeLin
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信