美文网首页程序员的一生
节流函数怎么写?

节流函数怎么写?

作者: Z不懂 | 来源:发表于2018-04-17 09:52 被阅读0次

    平时我们在开发中,会经常使用到resize和movesemove事件,这些事件会在短时间内频繁的执行事件绑定程序,我们知道频繁的操作DOM会带来很大的性能消耗,页面会促发回流和重绘。有时候页面会出现卡顿,在IE浏览器下可能直接崩溃。这时候节流函数就发挥作用了。

    什么是函数节流?

    简单讲就是让一个函数无法在短时间内连续调用,只有当上一次函数执行后过了规定的时间间隔,才能进行下一次该函数的调用。或者说你在操作的时候不会马上执行该函数,而是等你不操作的时候才会执行。

    函数截流的原理

    通过使用定时器,在操作的时候让函数延时执行,如果在这个时间内还在操作,则清除原来的定时器,再创建一个新的定时器执行

    方式一:

    最简单的操作方式,在操作的的时候清除上次的定时器,不操作的事后在执行callBack回调

    //封装
    /**
    *  @  { Function} callBack    回调程序    
    */
    function throttleFn(callBack){
        clearTimeout(method.timer);
        method.timer=setTimeout(()=>{
            method()
        },100)
    }
    
    //调用
    window.onresize=function(){
        throttleFn(callBack)
    }
    
    

    方式二

    优势在于把延迟时间当做变量,而且使用闭包保护私有变量,缺点就是虽然使用apply把调用throttleFn时的this上下文传给执行函数,但毕竟不够灵活

    //封装
    /**
    *  @  { Function} callBack    回调程序    
    *  @  { Number } delay  延时时间
    *  return  { Function }
    */
    function thorttleFn(callBack,delay){
        var timer=null;
        return function(){
            var context=this;
            clearTimeout(timer);
            timer=setTimeout(()=>{
                callBack.apply(context,arguments)
            },delay)
        }
    }
    
    //调用
    window.onresize=thorttleFn(myFunc,300)
    
    

    方式三(个人认为性能最优)

    拓展深化函数节流

    其实函数节流的出发点,就是让一个函数不要执行得太频繁,减少一些过快的调用来节流,减少性能消耗。当你在操作resize和mousemove事件的时候,浏览器其实是有设置一个时间间隔,这个时间是多少我们不清楚,而且他们没有提供参数去设置,所以需要我们在他们的基础上再去做一些改变。真正的节流应该是在可接受的范围内尽量延长这个调用时间,也就是我们自己控制这个执行频率,让函数减少调用以达到减少计算、提升性能的目的。假如原来是16ms执行一次,我们如果发现resize时每50ms一次也可以接受,那肯定用50ms做时间间隔好一点。

    /**
    *  @  { Function} callBack 回调程序    
    *  @  { Number } delay  延时时间
    *  @  { Number }  intervalTime  间隔时间
    *  return  { Function }
    */
    function thorttleFn(callBack,delay,intervalTime){
        var timer=null;  // 定时器变量
        var time=0;  // 时间变量
        return function(){
            var context=this;
            var curTime=new Date();  // 当前执行的时间
            clearTimeout(timer);  //  清除上次的定时器
            
            if(!time){
                time=curTime;
            }
            // 当前执行时间距离上次执行的时间是否大于等于间隔时间
            if(curTime - time >= intervalTime){
                time=curTime;
                callBack.apply(context,arguments)
            }else{
                timer=setTimeout(()=>{
                    callBack.apply(context,arguments)
                },delay)
            }
        }
    }
    
    //调用
    window.onresize=thorttleFn(myFunc,50,300)
    
    

    相关文章

      网友评论

        本文标题:节流函数怎么写?

        本文链接:https://www.haomeiwen.com/subject/cccukftx.html