Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

探讨javascript函数节流 #221

Open
confidence68 opened this issue Oct 17, 2016 · 0 comments
Open

探讨javascript函数节流 #221

confidence68 opened this issue Oct 17, 2016 · 0 comments
Labels

Comments

@confidence68
Copy link
Owner

前言

最近好忙,10月中旬了,才写10月份的第一篇文章。今天主要写写我们平时工作中需要的函数节流。可能有的朋友对函数节流没有意识。其实,在工作中,很多场景都需要我们进行js的节流。最常见的是屏幕伸缩resize,以及touchmove或者scroll等事件的时候。大家不知道有没有看我之前写的文章!jquery判断页面滚动条上滚下滚touchmove的滑动方向,大家在使用这些例子的时候,会发现页面不停的触发touchmove或者scroll因为这里没有关系到页面的重绘,因此,我在这里没有使用javascript函数节流。但是,当我们使用window.onresize的时候,也会不停的触发resize事件!这里就会关系到页面的重新绘制问题了。因此,在window的resize的时候,我们推荐大家使用函数节流的方式!

javascript函数节流简介

假如你对我上面一大坨文字感到头大,没关系,我在这里简单举例说明一下函数节流吧!例如当我们使用

 $(window).resize(function(){
            console.log("haorooms window resize");
        })

会发现:

enter image description here

这里会输出好多次。我们简单的缩小一下窗口,就会不停的触发!

这样在div很多的时候,页面不停重绘,要是遇到版本比较低的IE等,很可能会出现浏览器崩溃的现象!为了避免这种情况,我们可以用函数节流的方式。基本的思想是:第一次调用函数的时候,我们创建一个定时器,在指定时间间隔之后运行代码,第二次调用的时候,会清楚前一个定时器,并重新设置一个。如果前一个定时器已经执行过了,那么这个操作就没有有意了,如果定时器尚未执行,就会将其替换为一个新的定时器。目的是在执行函数停止了一段时间之后再执行。

用对象的方式可以如下写:

var haoroomstest={
            timeoutId:null,
            performProcessing:function(){               
                    console.log("resize");          

            },
            process:function(){
                clearTimeout(this.timeoutId);
                var that=this;
                this.timeoutId=setTimeout(function(){
                    that.performProcessing();
                },500)
            }
        }

这样之后,我们再用:

$(window).resize(function(){
haoroomstest.process();
})

enter image description here

这样就会减少请求,减少dom重绘,达到节流的目的!

函数节流其他方式

除了我们运用对象的方式,网上及资料中也介绍了关于函数节流的其他方法和方式,我下面简单介绍几种!

函数方式一

function throttle(method,context){
            clearTimeout(method.tId);
            method.tId=setTimeout(function(){
                method.call(context);
            },100);
        }

我们如下使用

 function resizeDIv(){
            console.log("haorooms")
        }

        $(window).resize(function(){
            throttle(resizeDIv)
        })

和上面对象实现了同样的效果!

函数方式二

网上还有一种比较流行的节流方式,我在这里写一下!

function throttle(method,delay){
            var timer=null;
            return function(){
                var context=this, args=arguments;
                clearTimeout(timer);
                timer=setTimeout(function(){
                    method.apply(context,args);
                },delay);
            }
        }

然后可以这么写:

  function resizeDIv(){
            console.log("haorooms")
        }

     window.onresize=throttle(resizeDIv,500);

新需求

我们在做模糊搜索智能联想提示的时候,会在input上面绑定keyup事件。但是我又不想触发的那么频繁,用上面的方式就会有问题。因此,在上面的函数基础上稍加改动,如下:

function throttle(method,delay,duration){
            var timer=null, begin=new Date();
            return function(){
                var context=this, args=arguments, current=new Date();;
                clearTimeout(timer);
                if(current-begin>=duration){
                     method.apply(context,args);
                     begin=current;
                }else{
                    timer=setTimeout(function(){
                        method.apply(context,args);
                    },delay);
                }
            }
}

这样触发就不会有之前那么频繁了!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant