IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

javascript函数的throttle和debounce

WEB前端开发 2013-07-08 22:43:51 累计浏览 3,190 次
本机暂存

上周写了window resize和scroll事件的基本优化,结果微博上交流的人还挺多,大家都提到了一个技术名词:“throttle”。

throttle

我们这里说的throttle就是函数节流的意思。再说的通俗一点就是函数调用的频度控制器,是连续执行时间间隔控制。主要应用的场景比如:

  • 鼠标移动,mousemove 事件

  • DOM 元素动态定位,window对象的resize和scroll 事件

有人形象的把上面说的事件形象的比喻成机关枪的扫射,throttle就是机关枪的扳机,你不放扳机,它就一直扫射。我们开发时用的上面这些事件也是一样,你不松开鼠标,它的事件就一直触发。回到window resize和scroll事件的基本优化提到的优化:

varresizeTimer=null;
$(window).on('resize',function(){
        if(resizeTimer){
            clearTimeout(resizeTimer)
        }
        resizeTimer=setTimeout(function(){
            console.log("window resize");
        },400);
    }
);

setTimeout和clearTimeout其实就是一个简单的 throttle,很多好的控制了resize事件的调用频度。

debounce

debounce和throttle很像,debounce是空闲时间必须大于或等于 一定值的时候,才会执行调用方法。debounce是空闲时间的间隔控制。比如我们做autocomplete,这时需要我们很好的控制输入文字时调用方法时间间隔。一般时第一个输入的字符马上开始调用,根据一定的时间间隔重复调用执行的方法。对于变态的输入,比如按住某一个建不放的时候特别有用。

debounce主要应用的场景比如:

  • 文本输入keydown 事件,keyup 事件,例如做autocomplete

这类网上的方法有很多,比如Underscore.js就对throttle和debounce进行封装。jQuery也有一个throttle和debounce的插件:jQuery throttle / debounce,所有的原理时一样的,实现的也是同样的功能。再奉上一个自己一直再用的throttle和debounce控制函数:

/*

* 频率控制 返回函数连续调用时,fn 执行频率限定为每多少时间执行一次

* @param fn {function}  需要调用的函数

* @param delay  {number}    延迟时间,单位毫秒

* @param immediate  {bool} 给 immediate参数传递false 绑定的函数先执行,而不是delay后后执行。

* @return {function}实际调用函数

*/

var throttle = function (fn,delay, immediate, debounce) {

   var curr = +new Date(),//当前事件

       last_call = 0,

       last_exec = 0,

       timer = null,

       diff, //时间差

       context,//上下文

       args,

       exec = function () {

           last_exec = curr;

           fn.apply(context, args);

       };

   return function () {

       curr= +new Date();

       context = this,

       args = arguments,

       diff = curr - (debounce ? last_call : last_exec) - delay;

       clearTimeout(timer);

       if (debounce) {

           if (immediate) {

               timer = setTimeout(exec, delay);

           } else if (diff >= 0) {

               exec();

           }

       } else {

           if (diff >= 0) {

               exec();

           } else if (immediate) {

               timer = setTimeout(exec, -diff);

           }

       }

       last_call = curr;

   }

};

/*

* 空闲控制 返回函数连续调用时,空闲时间必须大于或等于 delay,fn 才会执行

* @param fn {function}  要调用的函数

* @param delay   {number}    空闲时间

* @param immediate  {bool} 给 immediate参数传递false 绑定的函数先执行,而不是delay后后执行。

* @return {function}实际调用函数

*/

var debounce = function (fn, delay, immediate) {

   return throttle(fn, delay, immediate, true);

};

demo:http://www.css88.com/demo/throttle_debounce/

更多阅读:

http://www.alloyteam.com/2012/11/javascript-throttle/

http://remysharp.com/2010/07/21/throttling-function-calls/


同分类推荐文章

  1. translateZ() (2026-06-25 21:18:56)
  2. translateY() (2026-06-25 21:17:56)
  3. translateX() (2026-06-25 21:16:01)

查看更多 前端 文章 →

建议继续学习

  1. JQuery实现Excel表格呈现 (累计阅读 48,346)
  2. 深入理解Javascript之执行上下文(Execution Context) (累计阅读 18,401)
  3. 从输入 URL 到页面加载完成的过程中都发生了什么事情? (累计阅读 15,931)
  4. 图片动态局部毛玻璃模糊效果的实现 (累计阅读 14,845)
  5. 天朝第二代身份证号码的验证机制 (累计阅读 14,760)
  6. HTML 5 的data-* 自定义属性 (累计阅读 14,348)
  7. 分享一个JQUERY颜色选择插件 (累计阅读 14,222)
  8. 什么是全栈工程师? (累计阅读 14,035)
  9. 快速排序(Quicksort)的Javascript实现 (累计阅读 11,733)
  10. 7 天打造前端性能监控系统 (累计阅读 11,187)