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

对于“ 监听窗口大小变化 ”的功能,想必大家都不陌生,这玩意贼有用,比如 响应式网站设计 。(但是能用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)
}
})