防抖和节流

前端开发中,咱们的一些事件的响应比较慢或者须要请求接口完成的,咱们不但愿这些事件频繁执行,好比说须要对input输入的数据保存,监听keyup事件,若是每次键盘输入就执行保存请求,那样可能会产生不少频繁的请求,针对这种连续触发的高频率事件,函数防抖和函数节流给出了两种解决方法前端

防抖(debounce)

去抖动,方法是在函数触发时,设定一个周期延迟执行函数,若在周期内函数再次执行、则刷新延迟时间,直到最后执行函数,这里函数收集到的结果是最后一次操做的结果bash

简单的实现

var timer; // 定时器
function change (e) {
    if (timer) {
        clearTimeout(timer);
    }
    timer = setTimeout(function () {
        console.log(e.target.value);
        timer = void 0;
    }, 1000)
}
document.querySelector("#test").addEventListener('keyup', change);
复制代码

这里监听input的keyup事件,change方法执行的时候会首先判判定时器是否存在、若是存在则clear掉,若是不则新建一个定时器延迟1s执行app

封装

上面这样实现没毛病,可是却有一个问题,没有复用性,如今我来把他封装成一个公共的方法函数

function keyup (e) {
    console.log(e.target.value);
}

function debounce (method, delay) {
    var timer = void 0;
    return function () {
        var self = this;
        var args = arguments;
        timer && clearTimeout(timer);
        timer = setTimeout(function () {
            method.apply(self, args)
            timer = void 0;
        }, delay)
    }
}
document.querySelector("#test").addEventListener('keyup', debounce(keyup, 1000));
复制代码

节流(throttling)

节流的概念是设定一个周期,周期内只执行一次,如有新的事件触发则不执行,周期结束后又有新的事件触发开始新的周期ui

实现

好比说咱们监听onscroll判断获取当前的scrollTop、能够用到节流this

var start, timer, wait = 200
function scroll() {
    var self = this;
    var args = arguments;
    if (!start) {
        //第一次触发,设置start时间
        start = Date.now()
    }
    // 当前时间减去开始时间大于等于设定的周期则执行而且初始化start、timer
    if (Date.now() - start >= wait) {
        console.log('触发了')
        start = timer = void 0;
    } else {
        timer && clearTimeout(timer)
        timer = setTimeout(function () {
            scroll.apply(self, arguments)
        },wait)
    }
}
document.addEventListener('scroll', scroll)
复制代码

封装

function throttling (method, wait) {
    var start, timer
    return function run () {
        var self = this;
        var args = arguments;
        if (!start) {
            start = Date.now();
        }
        if (Date.now() - start >= wait) {
            method.apply(self, args)
            start = timer = void 0
        } else {
            timer && clearTimeout(timer)
            timer = setTimeout(function () {
                run.apply(self, args)
            }, wait)
        }
    }
}
function scroll() {
    console.log('触发了')
}
document.addEventListener('scroll', throttling(scroll, 200))
复制代码

这里须要注意的就是参数和this指向的问题spa

总结

节流和防抖各有特色,若是是须要一连串频繁的事件只执行最后一次选择防抖、其它能够选择节流,具体业务具体分析code

若文中有错误的地方望多多指正接口

相关文章
相关标签/搜索