函数节流

函数节流:

通俗概念:

降频,如果触发频次太快,需要降低触发次数的频率

为什么要函数节流

前端开发过程中,有-些事件或者函数,会被频繁地触发(短时间按内多次触发),最常 见的例
如,onresize , scroll , mousemove ,mousehover等,这些事件的触发频率很高,不做限制的话,有可
能一秒之内执行几十次、几百次,如果在这些函数内部执行了其他函数,尤其是执行了操作DOM的函
数(浏览器操作DOM是很耗费性能的,因为浏览器会根据真实dom的变化来进行重绘和重排) , 那不仅会造成计算机资源的浪费,还会降低程序运行速度,甚至造成浏览器卡死、崩溃,这种问题显然是致命的。所以就需要用到函数节流来节制一下,给他规定个时间来触发。

代码实现(以一个鼠标移动的案例为例)

window.onload = function(){
              var node = document.getElementById("div1")
              var i = 0;
              function handleMove(){
                  console.log(i++);
              }
              node.onmousemove = throttle(handleMove,2000);
          }

通过时间戳的方法节流:
第一次立即触发,往后每隔两秒触发一次

function throttle(func,wait){
              let prevDate = 0           //记录上次时间
              let curDate = Date.now();  //记录当前时间
              return function(){
                  const context = this;  
                  const arg = arguments;
                  //console.log(this)    //指向div
                  curDate = Date.now();
                  if(curDate - prevDate >= wait){      
 //当前触发事件的时间减去上次触发事件的时间大于等于延时的时间,也就是说在指定的时间内是永远都不会
 //去执行,因为根本就没有那段的函数啊,执行个桃子啊。
                      func.apply(context,arg);
                       prevDate = curDate;
                      // console.log(this)  //指向div
                  }
              }
          }
//也可以这样写:两种写法最终的this指向都是div,但是在setTimeout的写法中就不能省略获取this以及
//arguments的步骤,主要原因就是setTimeout中的this指向是window,如果不设置的话,最后在回调的时候
//就获取不到想要获取的目的值。
function throttle(func,wait){
              let prevDate = 0           //记录上次时间
              let curDate = Date.now();  //记录当前时间
              return function(){
                  curDate = Date.now();   //需要在return里面在记录一下当前的时间
                  if(curDate - prevDate >= wait){
                      func();
                      prevDate = curDate;
                  }
              }
          }

通过setTimeout方法:
第一次触发也是在指定时间后执行

function throttle(func,wait){
            let timer = 0;
            return function(){
                const context = this;
                const arg = arguments;
                if(!timer){
                    timer = setTimeout(function(){    
                        func.apply(context,arg);    
       //setTimeout中的this都是指向window的,所以必须强转
                        clearTimeout(timer);        
//这里就是第一次触发的时候在指定时间后执行,执行完毕第一次后关闭延时器,同时将timer设置为空,确保
//加下来的每次都会重新触发延时器,重新从零开始计时,避免因为多次触发事件而导致延时器一直关闭重启关
//闭重启。恰好与函数防抖相反。
                        timer = null
                    },wait)
                }
            }
        }

应用场景

1.懒加载、滚动加载、监听滚动条的位置
2.搜索框
3.防止表单重复提交

暂时能想到就这些,不过这并不一定都是这些场景才能应用,只要理解了原理后,想怎么用就怎么用,只要不妨碍程序的正常运行,不造成什么乱七八糟的后果,你随便。

总结

函数节流主要的目的就是降低触发的频率,从而减少页面的重绘和重排,减少浏览器的性能消耗。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值