MrFant
10/9/2019 - 1:28 PM

JS的函数节流和函数防抖

JS的函数节流和函数防抖

JS的函数节流和函数防抖

debounce 函数防抖

个人理解 函数防抖就是法师发技能的时候要吟唱,技能吟唱没完再按技能就会重新读吟唱。

throttle 函数节流

个人理解 函数节流就是fps游戏的射速,就算一直按着鼠标射击,也只会在规定射速内射出子弹。

结合应用场景

debounce

  • search搜索联想,用户在不断输入值时,用防抖来节约请求资源。

  • window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次

throttle

  • 鼠标不断点击触发,mousedown(单位时间内只触发一次)

  • 监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断

<html>
<title>函数节流和函数防抖</title>

<head>

</head>

<body>
    <p>
        <label>
            没有防抖的input
            <input id="unDebounce" type="text">
        </label>
    </p>

    <p>
        <label for="">
            防抖后的input
            <input id="debounce" type="text">
        </label>
    </p>

    <p>
        <label for="">
            节流后的input
            <input id="throttle" type="text">
        </label>
    </p>


    <script src="./test.js"></script>
</body>

</html>
//模拟一段ajax请求
function ajax(content) {
    console.log('ajax request ' + content+'     '+new Date().getSeconds())
}

let inputa = document.getElementById('unDebounce')

inputa.addEventListener('keyup', function (e) {
    ajax(e.target.value)
})

// --------------------------------------


function debounce(fun, delay) {
    return function (args) {
        // 每次执行都会把上一次的定时器清除,所以一直按的话会不停的清除创建定时器
        let that = this
        let _args = args
        console.log(fun.id)
        // fun.id 存储上一个timer的id,不能用块作用域变量所以绑定到fun上
        clearTimeout(fun.id)
        fun.id = setTimeout(function () {
            fun.call(that, _args)
        }, delay)
    }
}

let inputb = document.getElementById('debounce')

// 延迟时间,单位毫秒
let debounceAjax = debounce(ajax, 1200)

inputb.addEventListener('keyup', function (e) {
    debounceAjax(e.target.value)
})


// --------------------------------------

function throttle(fun, delay) {
    let last, deferTimer
    return function (args) {
        let that = this
        let _args = arguments
        let now = +new Date()
        // 当一次keyup事件来的时候判断距离上次调用ajax(而不是上次keyup)是否隔了delay时间
        // note:这里的last都是在调用时才修改值,所以为了保证最短间隔时间不低于delay
        if (last && now < last + delay) {
            clearTimeout(deferTimer)
            // 注意这里的定时器延时时间
            deferTimer = setTimeout(function () {
                last = now
                fun.apply(that, _args)
            }, last+delay-now)

        }else {
            last = now
            fun.apply(that,_args)
        }
    }
}

let throttleAjax = throttle(ajax, 1000)

let inputc = document.getElementById('throttle')
inputc.addEventListener('keyup', function(e) {
    throttleAjax(e.target.value)
})