js防抖动与函数截流

一 概念

  • 函数防抖(debounce):其概念其实是从机械开关和继电器的“去弹跳”(debounce)衍生出来的,基本思路就是把多个信号合并为一个信号。比如一个 input 每当输入结束后两秒执行搜索事件,这就是个很经典的防抖需求。

  • 函数节流(throttle):节流的概念可以想象一下水坝,你建了水坝在河道中,不能让水流动不了,你只能让水流慢些。换言之,你不能让用户的方法都不执行。如果这样干,就是debounce了。为了让用户的方法在某个时间段内只执行一次,我们需要保存上次执行的时间点与定时器。


     

二 防抖动

限制下次函数调用之前必须等待的时间间隔。正确实现 debouncing 的方法是将若干个函数调用合成 一次,并在给定时间过去之后仅被调用一次。

function debounce(func, delay) {
    var timeout;
    return function(e) {
        console.log("清除",timeout,e.target.value)
        clearTimeout(timeout);
        var context = this, args = arguments
        console.log("新的",timeout, e.target.value)
        timeout = setTimeout(function(){
          console.log("----")
          func.apply(context, args);
        },delay)
    };
};

var validate = debounce(function(e) {
    console.log("change", e.target.value, new Date-0)
}, 380);

// 绑定监听
document.querySelector("input").addEventListener('input', validate);

这个保证了正常的用户每输入1,2个字符就能触发一次。如果用户是输入法狂魔,也可以狠制他每输入3~6个字符触发一次。

这个方法的重点是,它在用户不触发事件的时,才触发动作,并且抑制了本来在事件中要执行的动作。

其他应用场合:提交按钮的点击事件。

二 函数截流

 
function throttle(fn, threshhold) {
 var timeout
 var start = new Date;
 var threshhold = threshhold || 160
 return function () {

 var context = this, args = arguments, curr = new Date() - 0
 
 clearTimeout(timeout)//总是干掉事件回调
 if(curr - start >= threshhold){ 
     console.log("now", curr, curr - start)//注意这里相减的结果,都差不多是160左右
     fn.apply(context, args) //只执行一部分方法,这些方法是在某个时间段内执行一次
     start = curr
 }else{
 //让方法在脱离事件后也能执行一次
     timeout = setTimeout(function(){
        fn.apply(context, args) 
     }, threshhold);
    }
  }
}
var mousemove = throttle(function(e) {
 console.log(e.pageX, e.pageY)
});

// 绑定监听
document.querySelector("#panel").addEventListener('mousemove', mousemove);

函数节流会用在比input, keyup更频繁触发的事件中,如resize, touchmove, mousemove, scroll。throttle 会强制函数以固定的速率执行。因此这个方法比较适合应用于动画相关的场景。

你可能感兴趣的:(js)