前端实现防抖功能的详细解读

发布于:2025-02-19 ⋅ 阅读:(22) ⋅ 点赞:(0)

在前端开发中,防抖(Debounce) 是一种优化技术,用于限制某个函数在短时间内被频繁调用的次数。它的核心思想是:在一定时间内,无论触发多少次事件,只执行最后一次操作。防抖通常用于处理用户输入、窗口调整、滚动事件等高频触发的场景,以减少不必要的计算或请求,提升性能。

1. 防抖的应用场景

常见场景

  1. 搜索框输入

    • 当用户在搜索框中输入内容时,每次按键都会触发搜索请求。如果不做防抖处理,可能会导致大量不必要的请求。

    • 使用防抖后,只有在用户停止输入一段时间后,才会触发搜索请求。

  2. 窗口调整(resize)

    • 当用户调整浏览器窗口大小时,会频繁触发 resize 事件。

    • 使用防抖后,只有在用户停止调整窗口大小一段时间后,才会执行相关逻辑。

  3. 滚动事件(scroll)

    • 当用户滚动页面时,会频繁触发 scroll 事件。

    • 使用防抖后,只有在用户停止滚动一段时间后,才会执行相关逻辑。

  4. 按钮点击

    • 当用户快速点击按钮时,可能会触发多次点击事件。

    • 使用防抖后,只有在用户停止点击一段时间后,才会执行点击逻辑。

2. 防抖的实现原理

防抖的核心原理是:

  • 设置一个定时器,在事件触发后等待一段时间。

  • 如果在这段时间内再次触发事件,则清除之前的定时器,重新开始计时。

  • 只有当事件停止触发一段时间后,才会执行目标操作。

3. 防抖的实现代码

原生 JavaScript 实现

function debounce(func, delay) {
  let timeout;

  return function (...args) {
    clearTimeout(timeout); // 清除之前的定时器
    timeout = setTimeout(() => {
      func.apply(this, args); // 在延迟后执行目标函数
    }, delay);
  };
}

使用示例

function onInput() {
  console.log('Input value:', document.getElementById('search').value);
}

const debouncedInput = debounce(onInput, 300);

document.getElementById('search').addEventListener('input', debouncedInput);

解释:

  • debounce 函数返回一个新的函数,这个新函数会在事件停止触发 delay 毫秒后执行目标函数 func

  • 每次事件触发时,都会清除之前的定时器并重新开始计时。

Vue 3 中使用 customRef 实现防抖

import { customRef } from 'vue';

function useDebouncedRef(value, delay = 300) {
  let timeout;

  return customRef((track, trigger) => {
    return {
      get() {
        track(); // 追踪依赖
        return value;
      },
      set(newValue) {
        clearTimeout(timeout); // 清除之前的定时器
        timeout = setTimeout(() => {
          value = newValue; // 更新值
          trigger(); // 触发更新
        }, delay);
      },
    };
  });
}

// 在组件中使用
export default {
  setup() {
    const debouncedValue = useDebouncedRef('');

    return {
      debouncedValue,
    };
  },
};

解释:

  • useDebouncedRef 是一个自定义的防抖 ref

  • 在 set 方法中,使用 setTimeout 延迟更新值,从而实现防抖效果。

4. 防抖与节流的区别

特性 防抖(Debounce) 节流(Throttle)
定义 在事件停止触发一段时间后执行一次操作 在一定时间间隔内只执行一次操作
适用场景 输入框搜索、窗口调整、滚动事件等 滚动事件、鼠标移动、按钮点击等
核心逻辑 每次触发事件时重置定时器 在一定时间间隔内只执行一次操作
执行时机 事件停止触发后执行 按照固定时间间隔执行

5. 防抖的实际应用示例

示例 1:搜索框防抖

<input type="text" id="search" placeholder="Search..." />

<script>
  function debounce(func, delay) {
    let timeout;
    return function (...args) {
      clearTimeout(timeout);
      timeout = setTimeout(() => {
        func.apply(this, args);
      }, delay);
    };
  }

  function search() {
    const query = document.getElementById('search').value;
    console.log('Searching for:', query);
    // 这里可以发起搜索请求
  }

  const debouncedSearch = debounce(search, 300);

  document.getElementById('search').addEventListener('input', debouncedSearch);
</script>

解释:

  • 用户在搜索框中输入内容时,只有在停止输入 300 毫秒后,才会触发搜索逻辑。

示例 2:窗口调整防抖

function debounce(func, delay) {
  let timeout;
  return function (...args) {
    clearTimeout(timeout);
    timeout = setTimeout(() => {
      func.apply(this, args);
    }, delay);
  };
}

function onResize() {
  console.log('Window resized:', window.innerWidth, window.innerHeight);
}

const debouncedResize = debounce(onResize, 200);

window.addEventListener('resize', debouncedResize);

解释:

  • 当用户调整窗口大小时,只有在停止调整 200 毫秒后,才会触发 onResize 逻辑。

6. 总结

  • 防抖 是一种优化技术,用于限制函数在短时间内被频繁调用的次数。

  • 它的核心思想是:在一定时间内,无论触发多少次事件,只执行最后一次操作。

  • 防抖常用于处理用户输入、窗口调整、滚动事件等高频触发的场景。

  • 通过防抖,可以减少不必要的计算或请求,提升性能。


网站公告

今日签到

点亮在社区的每一天
去签到