探讨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);
                }
            }
}

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

相关推荐
jump_jump几秒前
流式 HTML:从 htmx 片段装配到浏览器原生增量渲染
javascript·性能优化·前端工程化
红尘散仙2 分钟前
想写一个像样的终端 App?试试把 React 的开发体验搬进 Rust TUI
前端·rust
袋鼠云数栈UED团队44 分钟前
一套 Spec-First 的 AI 编程工作流
前端·人工智能
袋鼠云数栈前端1 小时前
一套 Spec-First 的 AI 编程工作流
前端·ai+
angerdream1 小时前
Android手把手编写儿童手机远程监控App之vue3 路由守卫
前端
不服老的小黑哥1 小时前
AI规范驱动编程-harness工程项目实战
前端
vivo互联网技术1 小时前
从 Web 到桌面:基于 Tauri 2.0 + Vue 3 打造 vivo 线下门店「大头贴」拍照体验系统
前端·rust
光影少年1 小时前
React 合成事件机制、和原生事件区别、事件冒泡阻止
前端·react.js·掘金·金石计划
没有鸡汤吃不下饭1 小时前
告别手动对接口:我用 OpenAPI JSON 做了一个前端接口同步 Skill
前端·ai编程
空栈独白1 小时前
NestJS实战-前后端联调
前端