浅谈JavaScript函数节流


Posted in Javascript onDecember 09, 2014

浏览器中某些计算和处理要比其他的昂贵的多。例如,DOM操作比起非DOM交互需要更多的内存和CPU时间。连续尝试进行过多的DOM相关操作可能会导致 浏览器挂起,有时候甚至会崩溃。尤其在IE中使用onresize事件处理程序的时候容易发生,当调整浏览器大小的时候,该事件连续触发。在 onresize事件处理程序内部如果尝试进行DOM操作,其高频率的更改可能会让浏览器崩溃。

     函数节流背后的基本思想是,某些代码不可以在没有间断的情况连续重复执行。第一次调用函数,创建一个定时器,在指定的时间间隔之后运行代码。当第二次调用 该函数时,它会清除前一次的定时器并设置另一个。如果前一个定时器已经执行过了,这个操作就没有任何意义。然而,如果前一个定时器尚未执行,其实就是将其 替换为一个新的定时器。目的是只有在执行函数的请求停止了一段时间之后才执行。

function throttle ( method , context ){
        clearTimeout ( method.tId );
        method.tId = setTimeout ( function () {
           method.call ( context );
         } , 100);
     }

应用举例:
     假设有一个<div/>元素需要保持它的高度始终等同于宽度,可作如下编码:

function resizeDiv(){
        var div = document.getElementById("mydiv");
        div.style.height = div.offsetWidth + "px";
      }
      window.onresize = function(){
        throttle(resizeDiv);
      }

这里,调整大小的功能被放入了一个叫做resizeDiv的单独函数中,然后onresize事件处理程序调用throttle()并传入 resizeDiv函数,而不是直接调用resizeDiv()。多数情况下,用户是感觉不到变化的,虽然给浏览器节省的计算可能非常大。

下面是其他网友的补充

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

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

$(window).resize(function(){
      console.log("haorooms window resize");
    })

会发现:

浅谈JavaScript函数节流

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

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

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

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(); })

浅谈JavaScript函数节流

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

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

函数方式一

function throttle(method,context){
      clearTimeout(method.tId);
      method.tId=setTimeout(function(){
        method.call(context);
      },100);
    }

我们如下使用

function resizeDIv(){
      console.log("haorooms")
    }

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

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

函数方式二

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

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

然后可以这么写:

function resizeDIv(){
      console.log("haorooms")
    }

   window.onresize=throttle(resizeDIv,500);

新需求

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

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

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

Javascript 相关文章推荐
淘宝网提供的国内NPM镜像简介和使用方法
Apr 17 Javascript
javascript随机显示背景图片的方法
Jun 18 Javascript
javascript中递归函数用法注意点
Jul 30 Javascript
JS实现浏览器状态栏文字闪烁效果的方法
Oct 27 Javascript
JavaScript调试的多个必备小Tips
Jan 15 Javascript
JavaScript实现的鼠标响应颜色渐变效果完整实例
Feb 18 Javascript
Angular路由ui-router配置详解
Aug 01 Javascript
微信小程序可滑动月日历组件使用详解
Oct 21 Javascript
小程序简单两栏瀑布流效果的实现
Dec 18 Javascript
jQuery实现简单评论功能
Aug 19 jQuery
解决vue项目axios每次请求session不一致的问题
Oct 24 Javascript
JavaScript实现瀑布流布局的3种方式
Dec 27 Javascript
node.js中的console.log方法使用说明
Dec 09 #Javascript
node.js中的console.warn方法使用说明
Dec 09 #Javascript
node.js中的console.info方法使用说明
Dec 09 #Javascript
浅谈JavaScript实现面向对象中的类
Dec 09 #Javascript
node.js中的console.trace方法使用说明
Dec 09 #Javascript
node.js中的console.time方法使用说明
Dec 09 #Javascript
node.js中的console.timeEnd方法使用说明
Dec 09 #Javascript
You might like
献给php初学者(入门学习经验谈)
2010/10/12 PHP
PHP数组及条件,循环语句学习
2012/11/11 PHP
PHP在线生成二维码(google api)的实现代码详解
2013/06/04 PHP
ThinkPHP 整合Bootstrap Ajax分页样式
2016/12/23 PHP
yii2.0框架实现上传excel文件后导入到数据库的方法示例
2020/04/13 PHP
微信公众号开发 自定义菜单跳转页面并获取用户信息实例详解
2016/12/08 Javascript
实例分析浏览器中“JavaScript解析器”的工作原理
2016/12/12 Javascript
利用PM2部署node.js项目的方法教程
2017/05/10 Javascript
推荐10款扩展Web表单的JS插件
2017/12/25 Javascript
Vue.js添加组件操作示例
2018/06/13 Javascript
React Native基础入门之调试React Native应用的一小步
2018/07/02 Javascript
详解使用React.memo()来优化函数组件的性能
2019/03/19 Javascript
node学习笔记之读写文件与开启第一个web服务器操作示例
2019/05/29 Javascript
Vue表单控件数据绑定方法详解
2020/02/05 Javascript
[01:11:15]VGJ.S vs Secret 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
[01:18:35]DOTA2-DPC中国联赛 正赛 Elephant vs LBZS BO3 第一场 1月29日
2021/03/11 DOTA
Python pass 语句使用示例
2014/03/11 Python
简单介绍Python2.x版本中的cmp()方法的使用
2015/05/20 Python
python数字图像处理之高级滤波代码详解
2017/11/23 Python
详解Python字典的操作
2019/03/04 Python
在SQLite-Python中实现返回、查询中文字段的方法
2019/07/17 Python
利用pyecharts实现地图可视化的例子
2019/08/12 Python
详解Python并发编程之从性能角度来初探并发编程
2019/08/23 Python
Django中自定义查询对象的具体使用
2019/10/13 Python
python实现批量处理将图片粘贴到另一张图片上并保存
2019/12/12 Python
浅析python字符串前加r、f、u、l 的区别
2021/01/24 Python
美国知名的网上鞋类及相关服装零售商:Shoes.com
2017/05/06 全球购物
德国柯吉澳趣味家居:Koziol
2017/08/24 全球购物
上海某公司.net方向笔试题
2014/09/14 面试题
掌上明珠Java程序员面试总结
2016/02/23 面试题
会议接待欢迎词
2014/01/12 职场文书
新年联欢会主持词
2014/03/27 职场文书
Nginx的rewrite模块详解
2021/03/31 Servers
selenium.webdriver中add_argument方法常用参数表
2021/04/08 Python
python实现三次密码验证的示例
2021/04/29 Python
React Fragment介绍与使用详解
2021/11/11 Javascript