js防抖和节流

js防抖和节流

应用场景

对于一些会频繁触发的事件,例如scroll、resize、keydown、keyup、mousemove等,如果正常绑定这些事件的话,那么可能在短时间内会多次连续的触发这些事件,如果这些事件中含有dom操作的话就会对浏览器造成相当大的负担。

对于这一类可能影响性能的事件,就需要做防抖动或者节流处理。

防抖动

定义:在一段时间内,多次触发事件后,事件函数只执行一次,且在最后一次触发后执行。

原理:对事件函数做延时处理,如果设定的延时时间内再次触发事件,则清除定时器,重新定时计算,这样就能保证一定时间内,只执行一次事件函数。

缺点:每次清除定时器后重新计时,则延时时间则变得更长,例如延时为30s,在29s的时候我重新触发了事件,则重新计时,59s后才会执行事件函数。

/*
*防抖动
*fn:回调函数
*delay:延迟时间
*/
export const debounce = (fn, delay) => {
    let timer = null;
    return () => {
        let args = arguments;
        if (timer) {//存在定时器则重新计时
            clearTimeout(timer);
        }

        timer = setTimeout(() => {
            fn.apply(this, args);
        }, delay);
    }
} 

节流

定义:在规定的事件内,只允许事件函数执行一次,无论触发多频繁,且规定时间内必定会执行一次事件函数。

原理:对事件函数做延时处理,在规定延时后执行事件函数,执行完成后,清除定时器,等待下次触发。

缺点:短时间内无法联系调用事件函数,只有等上一次触发规定延时过后才能调用。

/*
*节流
*fn:回调函数
*delay:延迟时间
*/
export const throttle = (fn, delay) => {
    let timer = null;
    return () => {
        let args = arguments;
        if (!timer) {
            timer = setTimeout(() => {
                fn.apply(this, args);
                clearTimeout(timer);
                timer = null;//上次执行完成后才重新计时
            }, delay);
        }
    }
}

可以看出:防抖和节流的定时器清除时机并不一致,从而导致了节流在规定时间内必定执行一次,防抖多次触发后只执行一次的效果。

需要注意的是:上面给出的2种方式第一次触发的时候都不是立即执行的,需要等待延迟时间结束才会执行第一次事件函数。如果需要立即执行,请自行修改。

另外:lodash.js中封装了防抖和节流的公共方法,大家可自行选择。

使用方法

document.onscroll = throttle(() => {
     console.log("这是节流")
     console.log("请书写需要的逻辑处理")
}, 1000);

你可能感兴趣的:(JavaScript)