函数防抖和函数节流

210 阅读1分钟

函数防抖(debounce)

  1. 函数防抖:间隔时间内,多次触发事件,以最后一次为准
  2. 应用场景:鼠标移入/移出、键盘输入框
  3. 案例解析:搜索框防抖案例

不防抖:用户只要输入,就会不停地打印;除非不输入

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <input type="search" placeholder="请输入搜索内容">
    <script>
        document.querySelector('input').oninput = function () {
            console.log(this.value)
        }
    </script>
</body>

</html>

防抖后:用户输入,只用中间停留时间不超过0.3秒就不会触发打印;超过了才会打印

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <input type="search" placeholder="请输入搜索内容">
    <script>
        // ◆防抖第一步:声明变量存储定时器
        let timeID = null
        document.querySelector('input').oninput = function () {
            // ◆防抖第二步:清除上一次定时器,以本次为准
            clearTimeout(timeID)
            // ◆防抖第三步:开启本次防抖定时器
            timeID = setTimeout(() => {
                console.log(this.value)
            }, 300)
        }
    </script>
</body>

</html>

细节:定时器中的 this ,默认指向 window ,如果定时器函数是箭头函数,则会访问上一次 this :事件源

函数节流(throttle)

  1. 函数节流:间隔时间内,事件只会触发一次
  2. 应用场景:高频事件、鼠标移动、鼠标滚动条
  3. 案例解析:鼠标滚动节流案例

不节流:只要鼠标滚动,就频繁触发

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    body {
      height: 3000px;
    }
  </style>
</head>

<body>
  <script>
    let j = 1
    window.onscroll = function () {
      j++
      console.log('鼠标滚动条触发次数:' + j)
    }
  </script>
</body>

</html>

节流之后:不管鼠标怎么滚动,间隔5秒才触发一次

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            height: 3000px;
        }
    </style>
</head>

<body>
    <script>
        //◆节流第一步:存储变量记录触发时间
        let time = null
        let i = 1
        window.onmousemove = function () {
            //◆节流第二步: 判断两次间隔是否超过节流时间
            let currentTime = Date.now()
            if (currentTime - time >= 5000) {
                i++
                console.log('鼠标移动触发次数:' + i)
                //◆节流第三步: 存储本次触发时间
                time = currentTime
            }
        }
    </script>
</body>

</html>

防抖与节流的异同点

  1. 相同点:都是为了优化函数执行频率,提高网页性能
  2. 不同点:
    • 防抖:优化“用户主动”触发的事件,多次触发以最后一次为准
    • 节流:优化“事件本身”执行原则频率,间隔时间只执行一次