开发过程中会遇到一些要频繁操作dom的情况,比如页面resize、scroll、keyup等导致整个UI卡顿甚至浏览器奔溃,记录一下方便下次直接粘贴~
函数去抖(debounce)
函数调用n秒后才会执行,如果函数在n秒内被调用的话则函数不执行,重新计算执行时间
function debounce(method,delay){
var timer=null;
return function(){
var context=this, args=arguments;
clearTimeout(timer);
timer=setTimeout(function(){
method.apply(context,args);
},delay);
}
}
function resizehandler(){
console.log(++n);
}
window.onresize=debounce(resizehandler,500);
使用场景
- 每次 resize/scroll 触发事件
- 文本输入的验证(连续输入文字后发送 AJAX 请求进行验证,验证一次就好)
- 表单Submit
- 吊大的请在评论区补充~
函数节流(throttle)
预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期
function throttle(method,duration){
var begin=new Date();
return function(){
var context=this, args=arguments, current=new Date();
if(current-begin>=duration){
method.apply(context,args);
begin=current;
}
}
}
function resizehandler(){
console.log(++n);
}
window.onresize=throttle(resizehandler,500);
使用场景
- DOM 元素的拖拽功能实现(mousemove)
- 射击游戏的 mousedown/keydown 事件(单位时间只能发射一颗子弹)
- 计算鼠标移动的距离(mousemove)
- Canvas 模拟画板功能(mousemove)
- 搜索联想(keyup)
- 监听滚动事件判断是否到页面底部自动加载更多:给 scroll 加了 debounce 后,只有用户停止滚动后,才会判断是否到了页面底部;如果是 throttle 的话,只要页面滚动就会间隔一段时间判断一次
- 吊大的请在评论区补充~
函数的节流和函数的去抖都是通过减少实际逻辑处理过程的执行来提高事件处理函数运行性能的手段,并没有实质上减少事件的触发次数,underscore 和 lodash 都提供了这两种方法,用起来还是不错的。