防抖函数、节流函数

95 阅读1分钟

防抖函数

实现的目的

当持续触发事件,在设定的时间内没有再触发该事件,事件处理函数会执行一次;如果未到设定的时间,又一次触发了事件,会重新开始计时。

实际应用

  • 搜索:输入结束后n毫秒(或秒)才进行搜索请求,n秒内又输入内容,重新计时;

  •  浏览器窗口执行resize,重新渲染页面

代码:

//第一种 非立即执行版
function debounce(func, wait) {
    let timeout;
    return function () {
        const context = this;
        const args = [...arguments];
        if (timeout) clearTimeout(timeout);
        timeout = setTimeout(() => {
            func.apply(context, args)
        }, wait);
    }
}

//第二种 立即执行版
function debounce(func, wait) {
    let timeout;
    return function () {
        const context = this;
        const args = [...arguments];
        if (timeout) clearTimeout(timeout);
        const callNow = !timeout;
        timeout = setTimeout(() => {
            timeout = null;
        }, wait)
        if (callNow) func.apply(context, args)
    }
}

function inputFun(value){
 console.log(`你输出的结果是${value}`)

}

let input = document.getElementById('test');

let debounceInput = debounce(inputFun,500);

input.addEventListener('keyup',function(e){

debounceInput(e.target.value)

})

节流函数

实现的目的

当持续触发事件的时候,设定的时间内,只调用一次事件处理函数。

实际应用

  •  Form表单的提交 鼠标不断点击触发,设定事件内只有一次生效。

代码实现

//第一种  用定时器的方式实现
function throttle(func, wait) {
    let timeout;
    return function () {
        let context = this;
        let args = arguments;
        if (!timeout) {
            timeout = setTimeout(() => {
                timeout = null;
                func.apply(context, args)
            }, wait)
        }
    }
}

 //第二种 时间戳版:
function throttle(func, wait) {
    var previous = 0;
    return function () {
        let now = Date.now();
        let context = this;
        let args = arguments;
        if (now - previous > wait) {
            func.apply(context, args);
            previous = now;
        }
    }
}

function handle(){
    console.log(Math.random())
}

document.getElementById('btn').onclick =  throttle(handle,1000)