# 防抖与节流

# 防抖

  • 调用事件n秒后才会执行该事件,若在这n秒内又调用该事件就会重新计算执行时间
  • input
  <input type="text" oninput="debounceHandler(event.target.value)">
   
  <script>
    function debounce(fn, wait) {
      let timer = null  
      return function () {
        if (timer !== null) {
          clearTimeout(timer) // 若有在计时则重新计时
        }
        timer = setTimeout(() => {
          fn.apply(this, arguments)
        }, wait)
      }
    }
    function onInput(value) {
      if (value) {
        console.log(value);
      }
    }
    const debounceHandler = debounce(onInput, 3000)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 节流

  • 持续触发事件时,保证一段时间内只调用一次事件处理函数
  • onresize, onscroll
  body {
      display: flex;
      justify-content: center;
    }

    li {
      width: 500px;
      height: 200px;
      list-style: none;
      display: flex;
      justify-content: center;
      align-items: center;
    }

    li:nth-child(2n) {
      background-color: whitesmoke;
    }

    li:nth-child(2n+1) {
      background-color: #ccc;
    }

    <ul>
      <li>xxxxxxxx</li>
    </ul>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    // 时间戳: 第一次立即执行
    function throttle(fn, wait) {
      let startTime = 0
      return function () {
        const curTime = Date.now()
        if (curTime - startTime >= wait) {
          fn.apply(this, arguments)
          startTime = curTime
        }
      }
    }
    function myScroll() {
      console.log(new Date());
    }
    const throttleHandler = throttle(myScroll, 3000)
    window.addEventListener('scroll', throttleHandler)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    // 定时器:在wait之后才执行(不会立即执行函数)
    // 最后一次停止触发后,因为定时器wait,还会最后执行一次
    function throttle(fn, wait) {
      let timer = null
      return function () {
        if (timer == null) {
          timer = setTimeout(() => {
            fn.apply(this, arguments)
            timer = null
          }, wait)
        }
      }
    }
    function myScroll() {
      console.log(new Date());
    }
    const throttleHandler = throttle(myScroll, 3000)
    window.addEventListener('scroll', throttleHandler)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    // 时间戳 + 定时器
    function throttle(fn, wait) {
      let timer = null
      let startTime = 0
      return function () {
        let curTime = Date.now()
        if (curTime - startTime >= wait) {
          fn.apply(this, arguments)
          startTime = curTime
        } else {
          if (timer == null) {
            timer = setTimeout(() => {
              fn.apply(this, arguments)
              startTime = curTime
              timer = null
            }, wait)
          }
        }
      }
    }
    function myScroll() {
      console.log(new Date());
    }
    const throttleHandler = throttle(myScroll, 3000)
    window.addEventListener('scroll', throttleHandler)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25