老规矩,什么是防抖?(节流在下面)
首先,在某些界面中有些用户行为会被频繁触发,而这些行为往往又伴随着DOM操作、AJAX请求等涉及页面重绘重排这些耗费性能的处理,极可能导致界面卡顿,甚至浏览器奔溃,
例如:使用百度搜索学习资源时,当向输入框输入 搜索词 后,才会在搜索框推荐与你搜索词相关的字词。而不是你每输入一个字就推荐一下。
函数防抖就是解决实时搜索(kepup)、拖拽(mousemove)等问题的。
下面,我们模拟一下这种情况。
//假设页面现在有一个搜索框
<input type="text" id = "input"></input>
//当输入时,用在控制台打印输入内容来模拟发送ajax的功能
var inp = document.getElementById("input");
inp.oninput = function(){
ajax();
}
function ajax(){
console.log(inp.value);
}
可以看到每输入一个字符就会在控制台打印出所有的内容。
那么怎么来实现防抖处理呢?
//重新绑定一下事件
var timer = null;//定时器
function ajaxA(e){ //实际事件被触发以后,js引擎传一个参数:事件对象e,我们也加进来
console.log(e,this.value);
}
inp.oninput = function(e){
var self = this;
var arg = arguments;
clearTimeout(timer);
timer = setTimeout(function(){
ajaxA.apply(self,arg);
},1000);
}
以上就是一个简单的防抖处理,接下来来封装一个具有普遍性的函数debounce(handler,delay)。
function debounce(handler,delay){
var timer = null;
return function(){
var self = this;
var arg = arguments;
clearTimeout(timer);
timer = setTimeout(function(){
handler.apply(self,arg);
},delay);
}
}
防抖?防抖?防抖?
然后就是节流了,来一个大大的分隔符(不太美观哦)
节流?节流?节流?
节流就是预定的一个函数,只有在大于等于执行周期时才会执行,周期内调用也不执行。
举个不太恰当的例子,老谭高中时是在一个小县城读书,学校厕所是那种所有坑位连通的那种,自动冲水,墙上有个水龙头一直往水箱放水,水箱内存够了一定量的水之后(放在节流里就是一段时间),水才会在重力的作用下冲下,并带走所有某物。
应用场景:窗口页面大小的调整及滚动/瀑布流布局/动态页面加载 /疯狂点击
首先节流的思想:
- 新建时间lastTime = 0
- 获取一下时间戳nowTime
- 比较两个时间的差值是否是我们所希望的等待的时间
- 如果时间差值足够,那么我们执行函数
- 如果时间差值太短不是我们希望的,那么不执行
接着就封装为一个函数:
function throttle(handler,wait){
var lastTime = 0;
return function(e){
var nowTime = new Date().getTime();
if(nowTime - lastTime >= wait){
handler.apply(this,argument);
lastTime = nowTime;
}
}
}
完整功能防抖节流请参阅下篇博客:防抖节流源码实现