2019-03-27

js的防抖和节流

据我所知防抖和节流都是为了优化作用,减轻浏览器和服务端的负担,防抖和节流俩个的英文要记住: debouncethrottle

函数防抖

所谓的函数防抖,可以这样做一个比喻,大家都学过生物,所以都知道反射弧的概念,现在有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大家都会互相点赞,每点赞一次如果都向服务器发送请求的话,服务器的负担就比较大了,这里可以使用函数防抖
  • 鼠标不断点击(函数节流)
  • 监听滚动事件,比如说是否滑动到底部自动加载更多

你可能感兴趣的:(2019-03-27)