天天看点

JavaScript进阶:函数节流的实现

前面文章说了“惰性单例”设计模式,它的作用是:在需要的时候再创建相应的节点。那么,如果对于必须提前创建好的节点,要求实时监测,但是这么做又会损伤性能,你怎么办?

对于“ 监听窗口大小变化 ”的功能,想必大家都不陌生,这玩意贼有用,比如 响应式网站设计 。(但是能用css就不要用js,css里的@media在一些低级功能上倒是个不错的选择)

对于这个功能,必会用到onresize函数,但是你每拖动一下,无论是有意的还是无意的,都会引起DOM的改变,从而引起整个页面树(DOM树 -> Rendem树)的重建就不怎么好玩了。

于是,函数节流 就出现了,它的根本是:缓慢响应,减少加载。也就是说:你拖动好几下,可能在你停下来以后,才能获取到这时的窗口大小,从而去做对应的改变:

这其中发挥主要作用的,就是setTimeout定时函数
var throttle=function (fn,interval) {
        var __self=fn,   //定义一个私有变量指向传入的函数——方便内部操作
            timer,
            firstTime=true;   //是否是第一次调用
        //   ***********************************自定义函数的结果要作判断条件,故在return好function中操作***********************************************
        return function () {
            var args=arguments,   //apply的两个参数——一个“修正的”this,一个传入的参数——比如这里argument就是指回调函数的interval操作
                __me=this;
            if(firstTime){
                __self.apply(__me,args);   //修正!   ——防止回调函数指向错误,用apply把函数的this指向调用的变量(对象)
                return firstTime=false;
            }
            if(timer){
                return false;
            }
            timer=setTimeout(function () {
                clearTimeout(timer);
                timer=null;
                __self.apply(__me,args);
            },interval||1100);
        };
    };
    window.onresize=throttle(function () {
        //执行事件体   比如:
        console.log(window.innerWidth)
    },1200);      
let bool=true;
window.addEventListener('resize',function(){
  if(bool){
    bool=false;
    setTimeout(()=>{
      bool=true;
      // 一些有趣的事情
      console.log(window.innerWidth);
    },1200)
  }
})      

继续阅读