函数的抖动以及节流

函数防抖和函数节流

  优化高频率执行js代码的一种手段,js中的一些事件如浏览器的resize、scroll,鼠标的mousemove、mouseover,input输入框的keypress等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能。为了优化体验,需要对这类事件进行调用次数的限制。

相关例子代码如下:

html一样比较简单:

  <input type="text" >

防抖

在事件被触发delay秒后再执行回调,如果在这n秒内又被触发,则重新计时。--->直白:比如click事件,在规定时间内只能执行一次,若多次点击,只执行最后一次;
    var input = document.getElementsByTagName('input')[0];
    input.onchange = debounce(function(e) {
        console.log(e.value)
      }, 2000)
      //防抖debounce
    function debounce(fn, delay) {
      var timer = null;
      return function() {
        // var _this = this,
        // _arguments = this.args;
        clearTimeout(timer)
        timer = setTimeout(() => {
          fn(this)
        }, delay)
      }
    }

以上代码就是函数防抖,如果直接执行input的onchange事件只要点击回车,就会输出;使用debounce降低了降低回调执行频率。节省计算资源。这样在2000内执行一次,若重复点击,这重新计算; 

注意问题:

①timer的作用域,这里使用回调是为了强调timer的作用域;

②this的指向问题,定时器中this的指向是window,所有可以使用箭头函数或者fn.apply(_this,_args)来处理;

节流

每隔一段时间,只执行一次函数。---》直白:比如click事件,在规定时间内,就执行一次,其他的点击都是无效的。

解决方法一:定时器节流。

①:利用一个开关switchT控制点击事件,在用一次性定时器在delay内再恢复

    var input = document.getElementsByTagName('input')[0];
    input.onchange = throttles(function(e) {
        console.log(e.value)
      }, 2000)
      // 节流throttles
    function throttles(fn, delay) {
      var switchT = false;
      return function() {
        if (switchT) return;
        switchT = true;
        setTimeout(() => {
          switchT = false;
        }, delay)
        fn(this)
      }
    }

②:通过时间戳延时

 // 节流throttles 
    function throttles(fn, delay) {
      var timer = null;
      return function() {
        if (timer) return;
        timer = setTimeout(() => {
          fn(this)
          timer = null;
        }, delay)
      }
    }

 

解决方法二:时间戳节流。使用时间来控制,当前时间与之前的时间间隔超过了delay,就可以再次执行

    var input = document.getElementsByTagName('input')[0];
    input.onchange = throttles(function(e) {
        console.log(e.value)
      }, 2000)
      // 节流throttles
    function throttles(fn, delay) {
      var previous = 0;
      return function() {
        var current = new Date();
        if (current - previous < delay) return;
        fn(this)
        previous = current;
      }
    }

常见应用场景

函数防抖的应用场景

连续的事件,只需触发一次回调的场景有:

  • 搜索框搜索输入。只需用户最后一次输入完,再发送请求
  • 手机号、邮箱验证输入检测
  • 窗口大小Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。

函数节流的应用场景

间隔一段时间执行一次回调的场景有:

  • 滚动加载,加载更多或滚到底部监听
  • 谷歌搜索框,搜索联想功能
  • 高频点击提交,表单重复提交

参考文章:https://segmentfault.com/a/1190000018445196#articleHeader0

 

此文章是自己的一个笔记总结,如若有不对的地方或者需要补充的地方,还望提出,谢谢!

posted @ 2019-04-09 21:41  H-LI  阅读(593)  评论(0编辑  收藏  举报