前文:网上很多函数节流与函数防抖的技术帖都是Ctrl+C、Ctrl+V,有的throttle函数写的都是错的,甚至拿debounce当函数节流讲。在这个坑里花了俩小时才搞明白,无奈~
函数节流:简单说就是单位时间delay内,函数fn只能执行一次。这样做的好处是,如窗口的onresize事件或滚动跳的onscroll事件,它们触发周期非常短,有时页面内容较多的时候易造卡顿问题,这个时候我们就要用到throttle函数来节制事件的触发周期。
function throttle(fn, delay) { delay || (delay = 250); //若没传触发周期,默认为250ms var last, //记录函数上次触发的时间 timer; return function () { var context = this; //存入调用当前函数的对象,本例中this是body var now = +new Date(), //记录当前时间 args = arguments; //若函数已执行过 且 当前时间距上次执行时间的间隔 小于 触发周期时,清除上次执行的定时器 if (last && now - last < delay ) { // hold on to it clearTimeout(timer); timer = setTimeout(function () { last = now; fn.apply(context, args); }, delay); } else { last = now; fn.apply(context, args); } }; } 调用方法: $('body').on('mousemove', throttle(function (event) { console.log('tick'); }, 1000)); 执行结果:鼠标在页面移动,1s内控制台只能打印一个tick
函数防抖 : 间间隔 t 内若再次触发事件,则重新计时,直到停止时间大于或等于 t 才执行函数
function debounce(fn, delay) { var timer = null; return function () { var context = this, args = arguments; clearTimeout(timer); timer = setTimeout(function () { fn.apply(context, args); }, delay); }; } 调用方法: $('body').keypress(debounce(function (event) { console.log('tick'); }, 2000)); 执行结果: 键盘持续按时(时间间隔小于2s),控制台无打印. 停止按后两秒,控制台打印一个tick