一、函数防抖(debounce):
当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。举个栗子,持续触发scroll事件时,并不执行handle函数,当1000毫秒内没有触发scroll事件时,才会延时触发scroll事件。
应用场景:
  • scroll事件滚动触发事件
  • 搜索框输入查询,如果用户一直在输入中,没有必要不停地调用去请求服务端接口,等用户停止输入的时候,再调用,设置一个合适的时间间隔,有效减轻服务端压力。
  • 表单验证
  • 按钮提交事件。
  • 浏览器窗口缩放,resize事件(如窗口停止改变大小之后重新计算布局)等。
二、函数节流(throttle):
当持续触发事件时,保证一定时间段内只调用一次事件处理函数。节流通俗解释就比如我们水龙头放水,阀门一打开,水哗哗的往下流,秉着勤俭节约的优良传统美德,我们要把水龙头关小点,最好是如我们心意按照一定规律在某个时间间隔内一滴一滴的往下滴。举个栗子,持续触发scroll事件时,并不立即执行handle函数,每隔1000毫秒才会执行一次handle函数。

应用场景:

  • DOM 元素的拖拽功能实现(mousemove)
  • 搜索联想(keyup)
  • 计算鼠标移动的距离(mousemove)
  • Canvas 模拟画板功能(mousemove)
  • 射击游戏的 mousedown/keydown 事件(单位时间只能发射一颗子弹)
  • 监听滚动事件判断是否到页面底部自动加载更多:给 scroll 加了 debounce 后,只有用户停止滚动后,才会判断是否到了页面底部;如果是 throttle 的话,只要页面滚动就会间隔一段时间判断一次.
三、实现:1、utils.js封装
// 防抖
export function debounce () {
  let timer = 0
  return function (callback, ms = 500) {
    clearTimeout(timer)
    timer = setTimeout(callback, ms)
  }
}

// 节流
export function throttle () {
  let timer
  var begin = new Date().getTime()
  return function (method, delay = 500) {
    var current = new Date().getTime()
    clearTimeout(timer)
    if (current - begin >= delay) {
      method()
      begin = current
    } else {
      timer = setTimeout(method, delay)
    }
  }
}
2、vue引用
<template>
  <div class="hello">
   <div @click="debounceButton">测试防抖</div>
   <br>
   <div @click="throttleButton">测试节流</div>
  </div>
</template>
<script>
import {debounce, throttle} from '@/common/utils'

const testDebounce = debounce()
const testThrottle = throttle()

export default {
  name: 'HelloWorld',
  methods: {
    debounceButton () {
      testDebounce(() => {
        console.log('测试防抖')
      }, 1500)
    },
    throttleButton () {
      testThrottle(() => {
        console.log('测试节流')
      }, 1000)
    }
  }
}
</script>