JS 防抖函数和节流函数

文章转载自:木上有水

什么是防抖?什么是节流?

  工作中我们经常会用一些方法监听某些事件的完成,比如scroll、resize、keyup等。

  常规事件触发的时候,比如scroll,会在短时间内触发多次事件绑定,造成性能的浪费!

1、防抖

  什么是防抖:多次事件触发后、事件处理函数只执行一次,并且是在触发操作结束时执行。

  原理:延时操作处理函数、若设定的延时到来之前、再次触发函数、则清除上一次的延时操作定时器、重新定时。(有点绕,试验一下就懂了)

  代码(例:scroll):

let timer;
window.onscrool = function(){
    if(timer){
        clearTimeout(timer);
    }
   console.log('方法在一直执行'); timer
= setTimeout(function(){ //滚动条位置   let scrollTop = document.body.scrollTop||document.documentElement.scrollTop;   timer = undefined;
     console.log('滚动条位置:' + scrollTop);
  },500);
}

   封装:

/**
 * 防抖函数
 * @param method 事件触发的操作
 * @param delay 多少毫秒内连续触发事件,不会执行
 * @returns {Function}
 */
function debounce(method,delay) {
    let timer = null;
    return function () {
        let self = this,
            args = arguments;
        timer && clearTimeout(timer);
        timer = setTimeout(function () {
            method.apply(self,args);
        },delay);
    }
}

window.onscroll = debounce(function () {
    let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    console.log('滚动条位置:' + scrollTop);
},200)

 

2、节流

  什么是节流:触发函数事件后,短时间内无法连续调用,只有执行完上一次的函数后,过了规定时间才可以调用下一次。

  原理:对处理函数进行延迟操作、若设定时间到来之前,再次出发事件、则清除上一次的延时操作定时器,重新定时。

  代码(例:scroll):

  

let startTime = Date.now(); //开始时间
let time = 500; //间隔时间
let timer;
window.onscroll = function throttle(){
let currentTime = Date.now();
if(currentTime - startTime >= time){
let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
console.log('滚动条位置:' + scrollTop);
startTime = currentTime;
}else{
clearTimeout(timer);
timer = setTimeout(function () {
throttle()
}, 50);
}
}

  封装:

/**
 * 节流函数
 * @param method 事件触发的操作
 * @param mustRunDelay 间隔多少毫秒需要触发一次事件
 */
function throttle(method, mustRunDelay) {
    let timer,
        args = arguments,
        start;
    return function loop() {
        let self = this;
        let now = Date.now();
        if(!start){
            start = now;
        }
        if(timer){
            clearTimeout(timer);
        }
        if(now - start >= mustRunDelay){
            method.apply(self, args);
            start = now;
        }else {
            timer = setTimeout(function () {
                loop.apply(self, args);
            }, 50);
        }
    }
}
window.onscroll = throttle(function () {
    let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    console.log('滚动条位置:' + scrollTop);
},800)
posted @ 2019-02-25 14:09  _Iniesta  阅读(516)  评论(0编辑  收藏  举报