js 防抖与节流

1.防抖

触发高频事件后n秒内函数只会执行一次,若是n秒内高频事件再次被触发,则从新计算时间
var time = null;
document.onmousewheel = function(e){
    if (time) {
        clearTimeout(time)
    }
    time = setTimeout( () => {
        /* 进行滚动操做 */
        time = null
    }, 100)
}
# 第一次滑动时 time 是null ,直接执行 setTimeout ,在 0.1s 内若是又继续滑动了滚轮,
# 就会清除上一次的 setTimeout ,直到在 0.1s 内没有滑动滚轮,就会执行 setTimeout 中
# 的内容。

2. 节流

高频事件触发,但在n秒内只会执行一次,因此节流会稀释函数的执行频率

下面是js代码,这种方式有点很差理解闭包

function throttle() {
    let canRun = true; // 经过闭包保存一个标记

    return function () {
        console.log(canRun)
        if (!canRun) return; // 在函数开头判断标记是否为true,不为true则return
        canRun = false; // 当即设置为false
        setTimeout(() => { // 将外部传入的函数的执行放在setTimeout中
            // 最后在setTimeout执行完毕后再把标记设置为true(关键)表示能够执行下一次循环了。
            // 当定时器没有执行的时候标记永远是false,在开头被return掉
            console.log(1)
            canRun = true;
        }, 1000);
    };
}
window.addEventListener('resize', throttle());

# 当函数被注册的时候,定义了 canRun 为 true,以后返回一个函数,
# 每当事件被触发的时候,执行返回的函数中的内容。首先判断 canRun,
# 若是为 true 就往下执行,而后设 canRun 为 false,执行定时器,
# 在接下来的 1s 内,若是再次触发 resize 事件,canRun 的值是 false ,
# 会直接 return 空,不会执行任何操做。当 1s 后执行了定时器中的
# 内容并设置 canRun 为 true 后,触发事件才会从新执行定时器。

***注意***
    1. 在添加事件的时候,后面的函数是加()的。正由于这个括号,因此在注册
       事件的时候,let canRun = true 会被执行一次,而在事件被触发的时候,
       let canRun = true 是不会被执行的,只有在被注册时会被执行一次。
    2. 触发事件之后,执行的是 throttle 函数返回的函数,而不是 throttle 
       函数。

这两种方式的区别:第一种是当 0.1s 内再次触发事件,会消除定时器,从新计算,适用于滚轮滚动后页面的切换。由于用户滚轮切换页面时,一次会滚动不少下;第二种是若是事件一直在触发,可是每 1s 会执行一次。函数

相关文章
相关标签/搜索