函数防抖&函数节流

函数防抖和节流都是控制事件触发频率的方法,应用场景也有很多,如:

1.输入框持续输入,将输入内容传给服务端进行校验;

2.多次触发点击事件;

3.onSroll滚动条滚动事件;

4.onmousemove鼠标移动事件;

案例

为了说明问题,假设一个场景:鼠标滑过一个div,触发onmousemove事件,它内部的文字会显示当前鼠标的坐标。它的效果是这样的

函数防抖&函数节流_第1张图片

>>函数防抖(debounce)

这里的“抖”就是函数被触发了,而一般的抖动都是多次并且持续性的。假设一个函数持续多次执行,我们希望它冷静下来几秒之后再执行。也就是当事件持续触发的时候不执行,等最后一次触发结束的一段时间之后再执行。

函数防抖&函数节流_第2张图片

>>函数节流(throttle)

节流就是让函数有节制的去执行,而不是每次触发都去执行。也就是在规定的时间内,只执行一次。

函数防抖&函数节流_第3张图片

>>代码实现

     /**
     * @desc 函数防抖
     * @param func 函数
     * @param wait 延迟执行毫秒数
     * @param immediate true 表立即执行,false 表非立即执行
     * 立即执行版的意思是触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的效果(第一次触发事件之后会执行,下一次触发之后如果距离上一次触发的时间小于n秒那就不会再执行,大于的话才会执行)
     * 非立即执行版的意思是触发事件后函数不会立即执行,而是在 n 秒后执行,如果在 n 秒内又触发了事件,则会重新计算函数执行时间(首次触发不执行,事件触发后的停顿时间超过n秒会自动执行)
     */
    function debounce(func, wait, immediate) {
        let timeout;
        return function () {
            let context = this;
            let args = arguments;
            if (timeout) clearTimeout(timeout);
            if (immediate) {
                var callNow = !timeout;
                timeout = setTimeout(() => {
                    timeout = null;
                }, wait)
                if (callNow) func.apply(context, args)
            }
            else {
                timeout = setTimeout(function () {
                    func.apply(context, args)
                }, wait);
            }
        }
    }

    /**
     * @desc 函数节流
     * @param func 函数
     * @param wait 延迟执行毫秒数
     * @param type 1 表时间戳版,2 表定时器版
     */
    function throttle(func, wait, type) {
        let previous,timeout;
        if (type === 1) {
            previous = 0;
        } else if (type === 2) {
            // let \\timeout;
        }
        return function () {
            let context = this;
            let args = arguments;
            if (type === 1) {
                let now = Date.now();
                if (now - previous > wait) {
                    func.apply(context, args);
                    previous = now;
                }
            } else if (type === 2) {
                if (!timeout) {
                    timeout = setTimeout(() => {
                        timeout = null;
                        func.apply(context, args)
                    }, wait)
                }
            }
        }
    }

    //调用
    document.getElementById("box-debounce").addEventListener('mousemove',debounce(function(e){
        document.getElementById("box-debounce").innerHTML = e.clientX +","+e.clientY;
    },1000,true))
    //调用
    document.getElementById("box-throttle").addEventListener('mousemove',throttle(function(e){
        document.getElementById("box-throttle").innerHTML = e.clientX +","+e.clientY;
    },1000,2))

你可能感兴趣的:(javascript)