防抖debounce

例:

const input = document.querySelector('input')
let timer = null

input.addEventListener('keyup', function(e) {
    if(timer) {
        clearTimeout(timer)
    }

    timer = setTimeout(function() {
        console.log(input.value)
        console.log(e.target)
        timer = null 
    },500)
})

封装成防抖函数

const debounce = function(fn, delay = 500) {
    let timer = null

    return function() {
        if(timer) {
            clearTimeout(timer)
        }

        timer = setTimeout(()=> {
            fn.apply(this,arguments)
            timer = null
        },delay)
    }
}


input.addEventListener('keyup', debounce(function(e){
    console.log(input.value)
    console.log(e.target)
},600))

防抖就是将频繁触发的事件,改为事件结束后延时触发,减少触发次数,从而达到节省资源的效果

实现的关键是

设立一个定时器,let timer = null

每次触发事件都会把定时器清除,if(timer) { clearTimeout(timer) }

并重新开启一个新定时器, timer=setTimeout()

当定时器结束后才会执行回调

节流throttle

例:

const div = document.querySelector('div')
let timer = null

div.addEventListener('drag', function(e) {
    if(timer) {
        return
    }

    timer = setTimeout(()=> {
        console.log(e.offsetX,e.offsetY)
        timer = null
    },100)
})

封装成节流函数

const throttle = function(fn, delay = 100) {
    let timer = null 

    return function() {
        if(timer) {
            return
        }

        timer = setTimeout(()=>{
            fn.apply(this,arguments)
            timer = null
        },delay)
    }
}

const div = document.querySelector('div')
div.addEventListener('drag', throttle(function(e){
    console.log(e.offsetX,e.offsetY)
},200))

节流就是将频繁触发的事件,改为一定时间段内只会触发一次

实现的关键是

设立一个定时器,let timer = null

触发事件后开启定时器,并且期间不能有其他定时器,if(timer) {return}

当定时器结束后会执行回调

总结

函数防抖:将几次操作合并为一此操作进行。原理是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。

函数节流:使得一定时间内只触发一次函数。原理是通过判断是否到达一定时间来触发函数。

区别: 函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数。 比如在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。这样的场景,就适合用节流技术来实现。