OBJUI

Javascript之防抖节流

2025-05-14 17:40:36 49

防抖和节流,这两种技术常用于优化高频触发的事件处理(如滚动、窗口大小调整、输入框搜索等):

1. 防抖函数(Debounce)

原理:在事件被触发后,延迟一段时间再执行回调函数。如果在延迟时间内再次触发事件,则重新计时。

/**
 * 防抖函数
 * @param {Function} func - 要执行的函数
 * @param {number} delay - 延迟时间(毫秒)
 * @param {boolean} immediate - 是否立即执行(可选,默认false)
 * @returns {Function} - 防抖处理后的函数
 */
function debounce(func, delay, immediate = false) {
  let timer = null;
  
  return function(...args) {
    // 如果已有定时器,清除它
    if (timer) clearTimeout(timer);
    
    // 是否需要立即执行
    if (immediate && !timer) {
      func.apply(this, args);
    }
    
    // 设置新的定时器
    timer = setTimeout(() => {
      timer = null;
      if (!immediate) {
        func.apply(this, args);
      }
    }, delay);
  };
}

2. 节流函数(Throttle)

原理:在一定时间内,只执行一次回调函数。即使在这段时间内多次触发事件,也只会执行一次。

/**
 * 节流函数(时间戳版)
 * @param {Function} func - 要执行的函数
 * @param {number} limit - 限制时间(毫秒)
 * @returns {Function} - 节流处理后的函数
 */
function throttle(func, limit) {
  let lastExecTime = 0;
  
  return function(...args) {
    const now = Date.now();
    
    // 如果距离上次执行超过了限制时间
    if (now - lastExecTime >= limit) {
      func.apply(this, args);
      lastExecTime = now;
    }
  };
}

3. 使用示例

// 假设有一个搜索框输入事件
const searchInput = document.getElementById('search-input');

// 使用防抖处理搜索输入
searchInput.addEventListener('input', debounce((e) => {
  console.log('搜索:', e.target.value);
  // 执行搜索逻辑...
}, 300));

// 使用节流处理滚动事件
window.addEventListener('scroll', throttle(() => {
  console.log('滚动事件被触发(节流)');
  // 执行滚动相关逻辑...
}, 200));

4. 区别总结

  • 防抖:适用于需要避免频繁触发的场景(如搜索框输入联想、按钮点击防止重复提交)。
  • 节流:适用于需要限制执行频率的场景(如滚动加载、窗口大小调整)。

5.vue中实现

// utils/tools.js
export function debounce(func, delay = 300) {
  let timer = null
  return function(...args) {
    if (timer) clearTimeout(timer)
    timer = setTimeout(() => {
      func.apply(this, args)
    }, delay)
  }
}

export function throttle(func, limit = 500) {
  let lastExecTime = 0
  return function(...args) {
    const now = Date.now()
    if (now - lastExecTime >= limit) {
      func.apply(this, args)
      lastExecTime = now
    }
  }
}

组件中使用

<template>
  <view>
    <button @click="debouncedHandle">防抖处理</button>
  </view>
</template>

<script>
import { debounce } from '@/utils/tools'

export default {
  data() {
    return {
      inputValue: ''
    }
  },
  created() {
    this.debouncedHandle = debounce(this.handleInput, 300)
  },
  methods: {
    handleInput() {
      console.log('处理输入:', this.inputValue)
    }
  }
}
</script>
更多精彩,请关注公众号

微信公众号