高频事件:触发频率高的事件,如 mousemove scroll keydown input …
给高频事件降频有2个手段:函数防抖,函数节流

函数防抖 - debounce

比如大家非常熟悉的联想查询功能。它是在用户进行键入的同时进行数据请求。但是键盘事件触发的频率是按照字母来计算的,不是按照汉字或者单词,如果每键入一个字母都触发一次数据请求,就非常的低效。在这种情况下,我们就有必要降低操作的频率,保证一定时间内,核心代码只执行一次。

在事件触发时,开始计时,在规定的时间(delay)内,若再次触发事件,将上一次计时(timer)清空,然后重新开始计时。保证只有在规定时间内没有再次触发事件之后,再去执行这个事件。

核心思路:触发事件后再n秒内只执行一次,如果再n秒内又触发了该事件,则重新计算时间。

  1. window.onload = function () {
  2. // 获取元素
  3. const btn = document.querySelector('input')
  4. // 需要防抖的方法
  5. function fn() {
  6. console.log(btn.value)
  7. }
  8. // 做防抖
  9. btn.addEventListener('input', debounce(fn, 1000))
  10. // 防抖方法
  11. function debounce(callback, delay) {
  12. let timer = null // 计时器
  13. return () => { // 闭包返回一个函数
  14. if (timer) { // 如果有计时器就清除计时器˝
  15. clearTimeout(timer)
  16. }
  17. timer = setTimeout(() => { // 重新赋值一个定时器
  18. callback()
  19. }, delay)
  20. }
  21. }
  22. }

个人代码书写思路:

  1. 定义一个debounce方法接受2个参数一个是需要做防抖的方法,一个是防抖的时间
  2. debounce方法中定义一个 timer变量用于存放计时器 初始值为0,然后返回一个函数 利用闭包访问这个timer
  3. 返回的函数中进行判断如果计时器存在就清除计时器,然后再创建一个计时器,计时器中的方法是要防抖的方法,时间是debounce的第二个参数

函数节流 - throttle

在连续触发的事件中,一定的时间内只执行一次我们的函数。

在事件触发之后,开始计时,在规定的时间(delay)内,若再次触发事件,不对此事件做任何处理。保证在规定时间内只执行一次事件.
核心思路:让每次一的函数触发都有一个固定的时间间隔,想要有时间间隔 必须知道上一次的执行时间

  1. window.onload = function () {
  2. // 获取元素
  3. const box = document.querySelector('div')
  4. // 需要节流的方法
  5. let num = 0;
  6. function count() {
  7. console.log(num++)
  8. }
  9. // 做节流
  10. box.addEventListener('mousemove', throttle(count, 500))
  11. // 节流方法
  12. function throttle(callback, delay) {
  13. let prev = 0 // 用于记录上次执行时间
  14. return function () {
  15. let now = Date.now() // 获得当前时间
  16. if (now - prev >= delay) { // 判断时间是否达到预设时间
  17. callback() // 执行回调函数
  18. prev = now; // 更新上次的执行时间
  19. }
  20. }
  21. }
  22. }

个人代码书写思路:

  1. 定义一个throttle方法接受2个参数一个是需要做节流的方法,一个是节流预设的时间
  2. throttle方法中定义一个 prev变量用于存上次执行的时间 初始值为0,然后返回一个函数 利用闭包访问这个prev
  3. 返回的函数中获取当前时间,进行判断当前时间和上次执行时间差是否达到预设时间,如果达到就执行需要执行的方法,然后更新上次执行的时间,将上次执行时间赋值为当前时间