JS 节流 防抖

144 阅读4分钟

节流

什么是节流

节流:单位时间内,频繁触发事件,只执行一次

应用场景:高频事件 mousemove scroll

开发使用场景:轮播图点击效果、鼠标移动、页面尺寸缩放resize、滚动条滚动 就可以加节流

假如一张轮播图完成切换需要300ms, 不加节流效果,快速点击,则嗖嗖嗖的切换

加上节流效果, 不管快速点击多少次, 300ms时间内,只能切换一张图片

image.png

封装节流函数(上)

节流代码基本素材

image.png

image.png

封装节流函数(中)

为什么需要定义节流函数?

将节流的代码封装成函数,可以优化代码的执行流程、减少代码不必要的执行,从而提高代码的性能

节流函数名一般叫throttle

步骤

  1. 定义throttle节流函数
  2. throttle形参命名为callback
  3. 节流函数必须要有返回值,返回值一定是一个函数
  4. 在节流函数返回值中调用callback
  5. 将节流函数与事件处理函数结合一起
  6. 将事件处理函数作为参数传递给节流函数

为什么节流函数必须要有返回值,并且返回值是一个函数:节流函数在使用的时候 函数名 throttle(), 是调用函数,无法再次调用执行,所以需要在节流函数里面写return 函数 这样可以多次执行

image.png

封装节流函数(下)#

能够完成节流函数的封装

问题导入

上一小结已经完成了节流函数的基本结构,但是节流的效果还没有实现

如何能够实现节流效果?

核心思路

利用时间相减:移动后的时间 - 刚开始移动的时间 >= 指定的时间 成立才调用事件处理函数

最后需要将 当前时间重新赋值为 开始时间

步骤

  1. 节流函数需要传递第二个参数,第二个参数代表时间
  2. 在节流函数中获取到当前时间戳 开始时间戳
  3. 在节流函数中的return 函数中也需要获取时间戳 移动后的时间戳
  4. 移动后的时间 - 刚开始移动的时间 >= 指定的时间 成立才调用事件处理函数
  5. 最后需要将 当前时间重新赋值为 开始时间

image.png

image.png

防抖

能够说出什么是防抖

什么是防抖?

防抖:单位时间内,频繁触发事件,只执行最后一次,如果在单位时间内又触发了事件,则会重新计算函数执行时间

应用场景:搜索框

举个例子:

  • 北京买房政策:需要连续5年的社保,如果中间有一年断了社保,则需要从新开始计算
  • 比如,我 2020年开始计算,连续交5年,也就是到2024年可以买房了,包含2020
  • 但是我 2024年断社保了,整年没交,则需要从2025年开始算第一年往后推5年… 也就是 2029年才能买房…
  • 步骤

  1. 获取输入框
  2. 注册input事件
  3. 获取输入框的值

image.png 问题: 搜索框只要输入内容就马上触发函数

实际: 用户只想搜索adidas (a, ad, adi, adid.. 但是每个字母都触发了一次(浪费资源流量/性能不高))

防抖函数目的: 提高性能(优化体验)

封装防抖函数(上)

能够将事件处理函数抽离成具名函数

问题导入

如何优化上面防抖函数代码?

将事件处理函数由原本的匿名函数抽取为具名函数

image.png

封装防抖函数(中)

能够写出防抖函数的基本结构

问题导入

为什么需要定义防抖函数?

将防抖的代码封装成函数,可以优化代码的执行流程、减少代码不必要的执行,从而提高代码的性能

防抖函数名一般叫debounce

步骤

  1. 定义debounce函数
  2. debounce函数里面的形参命名为callback
  3. 防抖函数必须要有返回值,返回值一定是一个函数
  4. 在防抖函数返回值中调用callback
  5. 将防抖函数与事件处理函数结合一起
  6. 将事件处理函数作为参数传递给防抖函数

image.png

image.png

封装防抖函数(下)

能够完成防抖函数的封装

问题导入

上一小结已经完成了防抖函数的基本结构,但是防抖的效果还没有实现

如何能够实现防抖效果?

核心思路

利用延时函数实现,当事件触发时,判断有没有延时函数,有就先清除,在延时函数里面调用 事件处理函数

  1. 防抖函数需要传递第二个参数,第二个参数代表时间
  2. 在防抖函数中定义timerId值为null
  3. 在防抖函数中的return 判断有没有延时函数,有就先清除
  4. 在延时函数里面调用 callback回调函数

image.png