js的防抖和节流
据我所知防抖和节流都是为了优化作用,减轻浏览器和服务端的负担,防抖和节流俩个的英文要记住: debounce
和throttle
函数防抖
所谓的函数防抖,可以这样做一个比喻,大家都学过生物,所以都知道反射弧的概念,现在有A,B俩个同学,现在同学A打了同学B,但是由于同学B的反射弧过长,过一段时间才反应过来有人打他,突然又想起一个梗,假如有一天你被女神亲了一下,当时你肯定反应不过来,过了一段时间你才卧槽,函数防抖也是这么一回事,你触发一个事件后,过了特定的时间才处理这个事件,但是如果在这个指定的事件内如果重复触发该事件,那么每触发一次事件就重新开始计时,上图
var input = document.getElementsByClassName('name')[0];
function aaa(){
console.log('hello world')
}
input.addEventListener('input',debounce(2000, aaa));
function debounce(time, fn){
var timeout = null;
console.log(timeout);
return function(){
if(timeout != null){
clearTimeout(timeout)
}
timeout = setTimeout(fn, time);
}
}
现在分析一下这个代码,为什么debounce
函数能够实现防抖,开始timeout
变量是null
的,触发input
事件会执行debounce
函数执行后返回的函数,为什么debounce
函数执行结束后,其中的匿名函数还能引用timeout
变量,因为返回的函数是一个闭包函数,每触发input事件,如果timeout不为空,就说明了定时器没有定时结束,那么马上会清除定时器,并重新开始计时,在指定的事件内每触发一次事件都会重新开始计时,如果指定时间内没有触发,那么就会执行执行的函数
函数节流
一段时间内我只能触发一次事件,举个栗子,有一些投票系统,一天只允许投一次票,重复触发投票事件是无效的,上图
var btn = document.getElementsByClassName('btn')[0];
function aaa(){
console.log('hello world');
}
btn.addEventListener('click', throttle(5000, aaa));
function throttle(delay, fn){
var pre = Date.now();
return function(){
var now = Date.now();
if(now - pre >= delay){
fn();
pre = Date.now();
}
}
}
这里面有几个问题: 假如现在这个页面挂在已经超过5秒钟,那么此时点击这个按钮是立即触发的,点击按钮后,重复点击的话,只有5秒钟之后才会输出hello world
,但是如果点击按钮后,5秒钟后点击,那么会立即执行,因为第一次点击按钮后已经开始计时了
应用场景
- 音乐软件搜索音乐,只有你输入后一段时间,在下拉列表中显示与你搜索有关的音乐,函数防抖
- 点赞以前用qq大家都会互相点赞,每点赞一次如果都向服务器发送请求的话,服务器的负担就比较大了,这里可以使用函数防抖
- 鼠标不断点击(函数节流)
- 监听滚动事件,比如说是否滑动到底部自动加载更多