探讨javascript函数节流

前言

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

javascript函数节流简介

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

javascript 复制代码
 $(window).resize(function(){
        	console.log("haorooms window resize");
        })

会发现:

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

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

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

javascript 复制代码
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(); })

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

函数节流其他方式

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

函数方式一

scss 复制代码
function throttle(method,context){
            clearTimeout(method.tId);
            method.tId=setTimeout(function(){
                method.call(context);
            },100);
        }

我们如下使用

javascript 复制代码
 function resizeDIv(){
        	console.log("haorooms")
        }

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

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

函数方式二

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

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

然后可以这么写:

javascript 复制代码
  function resizeDIv(){
        	console.log("haorooms")
        }

     window.onresize=throttle(resizeDIv,500);

新需求

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

javascript 复制代码
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);
                }
            }
}

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

相关推荐
萌新小码农‍4 分钟前
Vue集成MarkDown
前端·javascript·vue.js
前端小巷子11 分钟前
深入理解XSS攻击
前端·安全·面试
mgx_71816 分钟前
windows指定某node及npm版本下载
前端·npm·node.js
Korloa16 分钟前
浅谈npm,cnpm,pnpm,npx,nvm,yarn之间的区别
前端·npm·node.js
DoraBigHead30 分钟前
作用域链与执行上下文的地下迷宫
前端·javascript·面试
0wioiw01 小时前
Flutter基础(前端教程⑧-数据模型)
前端·flutter·状态模式
一笑code1 小时前
UC浏览器PC版自2016年后未再更新不支持vue3
前端·vue
好记性不如2 小时前
在前端项目中是如何解决跨域的
前端
前端 贾公子8 小时前
pnpm 的 resolution-mode 配置 ( pnpm 的版本解析)
前端
伍哥的传说9 小时前
React 自定义Hook——页面或元素滚动到底部监听 Hook
前端·react.js·前端框架