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

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

相关推荐
南囝coding4 小时前
《独立开发者精选工具》第 018 期
前端·后端
小桥风满袖4 小时前
极简三分钟ES6 - ES9中for await of
前端·javascript
半花4 小时前
i18n国际语言化配置
前端
编程贝多芬4 小时前
Promise 的场景和最佳实践
前端·javascript
Asort5 小时前
JavaScript 从零开始(四):基础语法详解——从变量声明到数据类型的完全指南
前端·javascript
木木jio5 小时前
前端大文件分片上传 —— 基于 React 的工程化实现
前端·javascript
南雨北斗5 小时前
JS的对象属性存储器
前端
Lotzinfly5 小时前
12个TypeScript奇淫技巧你需要掌握😏😏😏
前端·javascript·面试
一个大苹果5 小时前
setTimeout延迟超过2^31立即执行?揭秘JavaScript定时器的隐藏边界
javascript
开源之眼5 小时前
React中,useState和useReducer有什么区别
前端