微信小程序实现输入框防抖

901 阅读3分钟

防抖

在小程序上使用之前得先介绍一下防抖。无非就是将一个频繁的操作延迟触发并且同时减少触发次数。 本质就是利用闭包保存定时器数据,并且在延迟时间内频繁触发会清除上一次的定时器操作。最后能触发的只能是触发事件之后的延迟时间内不再进行触发事件,则该在延迟时间结束后事件执行。(假设定时器设置的延迟时间为 500ms,第一次触发事件,第二次触发事件和第一次的时间间隔小于500ms,则清除第一次事件的触发,第三次触发事件和第二次的时间间隔若小于 500ms,则第二次不执行,... 直到第N次触发事件后的 500ms 不进行事件的触发,则第N次事件执行)

/**
 * 防抖函数
 * @param {Function} fn 需要进行防抖的函数引用
 * @param {Number} wait 延迟时间
 */
function debounce(fn, wait) {
    let timer;  // 关键
    return function () {  // 最终交由输入框执行的是这个返回函数,而不是debounce(fn,wait),关键
        clearTimeout(timer); // 清除上一次的定时器
        timer = setTimeout(() => {   // 设置新的定时器
            fn.apply(this, arguments)  // 执行需要执行的防抖函数(例如输入事件)
        }, wait); // 设置延迟时间
    }
}

微信小程序输入事件防抖

注:本次例子是在小程序中封装的输入框组件,请结合自己需求进行相应灵活更改。 输入框组件的 data 对象

  /**
   * 组件的初始数据
   */
  data: {
    // 延迟时间毫秒
    delay: 500,
    // 执行防抖函数的返回函数引用
    delayFun: null,
  },
  1. 首先必须有一个防抖函数(这是废话),可用上面的防抖方法。
/**
  * 防抖
  */
    debounce(fn, delay) {
      let timer = null;
      return function () {
        if (timer) {
          clearTimeout(timer);
        }
        timer = setTimeout(() => {
          fn.apply(this, arguments);
        }, delay);
      }
    },
  1. 触发父组件的事件(仅在自己封装的输入框组件内可使用)
   /**
     * 向父组件触发 input 事件,可携带参数
     * @param {String} eventName 事件名称
     * @param {Any} value 传递的参数
     */
    triggerEventToFather(eventName, value) {
      this.triggerEvent(eventName, value);
    }
  1. 执行防抖函数以获取防抖函数中的返回函数。 这个关键,因为输入框输入事件进行防抖的是 debounce(fn,delay) 这个函数中的 return 出来的返回函数。
    // 执行防抖函数
    handleDebounceFn(debounceFn, ...arg) {
      return debounceFn(arg[0], arg[1]);
    },
  1. 在组件的生命周期钩子中实现防抖函数以获取返回函数
lifetimes: {
    // 组件创建完成
    attached: function () {
      // 执行防抖函数,返回函数(防抖函数的返回函数)
      // 注:this.handleDebounceFn(第一个参数是防抖函数,第二个参数是需要进行防抖的方法这里指的是触发父组件的函数,第三个参数是延迟时间) 返回的是防抖函数执行后的返回函数,最后保存函数引用交由输入框的输入事件执行,则整个输入防抖完成。
      let delayFun = this.handleDebounceFn(this.debounce, (eventName, value) => {
        this.triggerEventToFather(eventName, value)
      }, this.data.delay);
      // 将this.handleDebounceFn 函数的返回的函数引用保存到 data 中。
      this.setData({
        delayFun
      })
    },
  },
  1. 输入框的输入事件
    // 输入框的事件
    handleInput(e) {
      // 防抖-输入
      // 执行 data 中的 delayFun 函数
      this.data.delayFun("search-input", e.detail.value);
    },
  1. 在父组件中触发 search-input 事件即可。