javaScript-防抖与节流
2022-02-18·3min
type
Post
summary
status
Published
category
tags
slug
date
Feb 18, 2022
password
icon
在前端开发中,某些场景下会遇到一些频繁的事件触发,比如:
- window 的 resize、scroll
- mousedown、mousemove
- keyup、keydown
如果这些频繁的事件触发后是一些复杂的回调操作,那么就会导致性能浪费,甚至程序崩溃。
防抖和节流的出现就是为了遏制频繁触发的事件回调。
防抖
防抖的原理就是:事件触发n秒后才执行回调,如果这n秒内事件再次触发,重新计时。
防抖分为非立即执行版本和立即执行版本。
非立即执行版防抖
非立即执行防抖就是传统的防抖,事件触发n秒后才执行回调函数。
实现如下:
立即执行版防抖
立即执行防抖就是事件第一次触发时马上执行回调,然后隔n秒后才可以触发第二次,如果这n秒内事件再次触发,重新计时。
实现如下:
节流
节流的原理就是:事件频繁触发但是n秒内只会执行一次回调函数,也就是会稀释事件回调的执行频率
关于节流的实现,有两种实现方式,一种是使用时间戳,一种是设置定时器。
时间戳版节流
原理就是设立一个时间戳,当事件触发时取出当前的时间戳,然后减去之前的时间戳(最一开始值设为0),如果大于设立的时间周期,就执行函数并更新时间戳为当前的时间戳,如果小于就不执行。
实现如下:
由于第一次进入time默认是0,
now - time
第一次都会大于规定的时间(除非传入一个特别大的时间),所以第一次事件回调立刻执行,当停止触发事件后,不会再执行回调。定时器版节流
原理就是设立一个定时器,定时器存在时就不执行回调,当事件触发时会启动定时器,定时器到期后会把自己赋值为null。
实现如下:
由于基于定时器,所以会有延后执行的特性,第一次事件触发时不会立即执行,事件停止触发后过一段时间还会执行一次。
需要注意的点
- 注意this的指向,如果不用apply会导致fn的this指向window。
- JS在事件处理函数中会提供事件对象event,要将这个事件对象传递给fn。