防抖(debounce):在没有被执行前,又触发,重新开始计时

应用场景:

  • 防止连续多次点击按钮,提交信息。
  • 搜索输入框,减少请求次数。
  • 判断scroll是否滑到底部
  • 即只需执行连续操作的最后一次
class Debounce {
    constructor(time) {
        this.time = time
        this.clear = null
    }

    setTime() {
        clearTimeout(this.clear)
        this.clear = setTimeout(() => {
            console.log('ececute code', new Date().getSeconds())
        }, this.time)
        
    }
}
const executeFn = new Debounce(2000)

/* 点击事件模拟 */
var clearTime = ''
document.body.addEventListener('click',() => {
    clearTimeout(clearTime) // 清除连续点击最后一次的前面的所有点击
    clearTime = setTimeout(() => {
        console.log('执行最后一次的点击')
    }, 2000)
})

节流(throttle):规定时间内无论被触发多少次,都执行一次

应用场景:

  • 连续的操作,不仅仅是最后一次触发需要执行,中途的也需要执行,但不需太过频繁

  • 计时器的方式实现

function throttleTime() {
    var flag = true
    return function() {
        if(flag) {
            flag = false
            setTimeout(() => {
                console.log(233333)
                flag = true
            }, 2000)
        }
    }
}
  • 时间戳的方式实现
function throttle (time) {
    let startTime = Date.now()
    
    return () => {
        const nowTime = Date.now()
        if(nowTime - startTime > time){
            console.log('execute code', new Date().getSeconds())
            startTime = Date.now()
        }
    }
}

// 模拟scroll滑动操作
let i = 0
const fn = throttle(2000)
const clear = setInterval(() => {
    i++
    if (i>50) clearInterval(clear)
    fn()
    console.log('time', i)
}, 1000)

鼠标移动实例

<div id="move" style="height: 500px;background-color: rgb(0, 255, 200);"></div>
document.getElementById('move').addEventListener('mousemove', mouseMove(printLog))

function printLog(e) {
    console.log(e.clientX, e.clientY);
}

function mouseMove(callback) {
    var startTime = Date.now(), timeInterval = 2000, timeout='';

    return function (event) {
        var  timeNow = Date.now();
        // 当前时间与初始时间的间隔大于设定的时间间隔
        if(timeNow-startTime >  timeInterval) {
            callback(event)
            startTime = timeNow
        } else {
            /* 保证如果触发滚动时间小于时间间隔,上面的代码不会执行 */
            // 在动作完成后间隔2s执行最后一次
            clearTimeout(timeout)
            timeout = setTimeout(function() {
                console.log('last');
                startTime = timeNow
                callback(event)
            }, timeInterval);
        }
    }
}
Last Updated:
Contributors: Warren