防抖和节流,代码实现

防抖和节流

什么情况下会用到防抖和节流呢?在绑定一些事件的时候,如resize,鼠标移动等。。

就是持续触发事件的时候。

有时候我们并不希望在事件持续触发时,频发的去执行函数,所以需要用到防抖和节流。

什么是防抖?(防抖节流插件:underscore.js)

  • 原理: 事件响应函数在一段时间后才执行,如果在这段时间内再次调用,则重新计算执行时间;当预定的时间内没有再次调用该函数,则执行响应函数。

  • 一般防抖还是用的比较多的

  • 应用场景:

    • scroll事件滚动触发
    • 搜索框输入查询
    • 表单验证
    • 按钮提交事件
    • 浏览器窗口缩放,resize事件
  • 例子:

    // 防抖函数
    function debounce(func, wait, immediate) {
      let timeout;
      return function () {
        // event指向问题
        let args = arguments;
        // 改变函数this指向问题
        let context = this;
        clearTimeout(timeout);
        if (immediate) {
          // 立即执行
          let callnow = !timeout;
          timeout = setTimeout(() => {
            timeout = null;
          }, wait);
          // 立即执行
          if (callnow) func.apply(context, args);
        } else {
          // 不会立即执行
          timeout = setTimeout(() => {
            func.apply(context, args);
          }, wait);
        }
      };
    }
    
    let count = 0;
    let container = document.querySelector("#container");
    function doSomeThing(e) {
      console.log(e);
      container.innerHTML = count++;
    }
    
    container.onmousemove = debounce(doSomeThing, 300, false);
    

什么是节流?

  • 原理:如果持续触发事件,每隔一段时间,只执行一次事件

  • 应用场景:

    • dom元素的拖拽功能实现
    • 射击游戏
    • 计算鼠标移动的距离
    • 监听scroll滚动事件
  • 例子:

    // 节流函数
    function throttle(func, await, options) {
      let timeout, args, context;
      let old = 0;
      if (!options) options = {};
      let later = function () {
        old = new Date().valueOf();
        timeout = null;
        func.apply(context, args);
      };
      return function () {
        // event指向问题
        args = arguments;
        // 改变函数this指向问题
        context = this;
        let now = new Date().valueOf();
        if (!options.leading &&  !old) {
          old = now;
        }
    
        // 第一次立即执行
        if (now - old > await) {
          if (timeout) {
            clearTimeout(timeout);
            timeout = null;
          }
          func.apply(context, args);
          old = now;
        }else if (!timeout && options.trailing) {
          timeout = setTimeout(later, await);
        }
      };
    }
    
    let count = 0;
    let container = document.querySelector("#container");
    function doSomeThing(e) {
      console.log(e);
      container.innerHTML = count++;
    }
    
    container.onmousemove = throttle(doSomeThing, 1000, {
      leading: true,
      trailing: false,
    });
    

你可能感兴趣的:(防抖和节流,代码实现)