美文网首页
JavaScript基础(四)防抖

JavaScript基础(四)防抖

作者: 前端开发爱好者 | 来源:发表于2019-03-15 00:35 被阅读0次

需求

在日常的前端开发中,一般会遇到一些会被频繁触发的事件,比如:window.resize,window.scroll,mousedown,mousemovekeydown,keyup,或者输入框等。这些函数或者是事件一般会被非常频繁的触发。

方案

为了解决这个问题一般会有两种解决方案:防抖(debounce)和节流(throttle)

防抖

原理:假定时间间隔是n秒。那么就是在函数第一次被调用时延时n秒后执行。在这n秒期间之内,再次触发,则以新的事件为准

第一版实现

function deBounce(func, wait) {
    var timeFlag;
    return function () {
        clearInterval(timeFlag);
        timeFlag = setTimeout(func, wait)
    }
}

第二版实现

第一版实现中会存在this指向不正确的问题


function deBounce(func, wait) {
    var timeFlag;
    return function () {
        var context = this;
        clearInterval(timeFlag);
        timeFlag = setTimeout(function () {
            func.apply(context)
        }, wait)
    }
}

或者使用bind
function deBounce(func, wait) {
    var timeFlag;
    return function () {
        clearInterval(timeFlag);
        timeFlag = setTimeout(func.bind(this), wait)
    }
}

第三版实现

第二版中的实现存在传参的问题

function deBounce(func, wait) {
    var timeFlag;
    return function () {
        var context = this;
        var args = arguments
        clearInterval(timeFlag);
        timeFlag = setTimeout(function () {
            func.apply(context, args)
        }, wait)
    }
}

或者bind

function deBounce(func, wait) {
    var timeFlag;
    return function (...args) {
        clearInterval(timeFlag);
        timeFlag = setTimeout(func.bind(this, ...args), wait)
    }
}

或者es6
const deBounce = (func, wait) => {
    let timeFlag;
    return function (...args) {
        clearInterval(timeFlag);
        timeFlag = setTimeout(func.bind(this, ...args), wait)
    }
};

第四版实现

有时会有需要立即执行的需求。

function deBounce(func, wait, immediate) {
    var timeFlag;
    return function () {
        var context = this;
        var args = arguments;
        timeFlag && clearInterval(timeFlag);
        if (immediate) {
            var callNow = !timeFlag;
            timeFlag = setTimeout(function () {
                timeFlag = null
            }, wait);
            if (callNow) func.apply(context, args)
        } else {
            timeFlag = setTimeout(function () {
                func.apply(context, args)
            }, wait)

        }
    }
}
// 或者

const deBounce = (func, wait, immediate) => {
    let timeFlag;
    return function (...args) {
        clearInterval(timeFlag);
        if (immediate) {
            const oldFlag = !timeFlag;
            timeFlag = setTimeout(() => {
                timeFlag = null
            }, wait);
            oldFlag && func.apply(this, args)
        } else {
            timeFlag = setTimeout(func.bind(this, ...args), wait)
        }
    }
};

第五版

第四版的函数仍然存在部分问题。就是当函数立即执行时。可能需要函数的返回值,所以修改后有下面第五版

function deBounce(func, wait, immediate) {
    var timeFlag;
    var deBounced = function () {
        var context = this;
        var args = arguments;
        var result;
        timeFlag && clearInterval(timeFlag);
        if (immediate) {
            var callNow = !timeFlag;
            timeFlag = setTimeout(function () {
                timeFlag = null
            }, wait);
            if (callNow) result = func.apply(context, args)
        } else {
            timeFlag = setTimeout(function () {
                func.apply(context, args)
            }, wait)

        }
        return result
    };
    deBounced.cancel = function () {
        clearTimeout(timeout);
        timeout = null;
    };
    return deBounced;
}

// es6
const deBounce = (func, wait, immediate) => {
    let timeFlag;
    const deBounced = (...args) => {
        clearInterval(timeFlag);
        if (immediate) {
            const oldFlag = !timeFlag;
            timeFlag = setTimeout(() => {
                timeFlag = null
            }, wait);
            oldFlag && func.apply(this, args)
        } else {
            timeFlag = setTimeout(func.bind(this, ...args), wait)
        }
    };
    deBounced.cancel = () => {
        clearTimeout(timeFlag);
        timeFlag = null;
    };
    return deBounced
};

相关文章

  • JavaScript基础(四)防抖

    需求 在日常的前端开发中,一般会遇到一些会被频繁触发的事件,比如:window.resize,window.scr...

  • 登登

    基础知识点与高频考题 JavaScript基础 防抖/节流 new 的实现原理,模拟实现一下 this指向 如果用...

  • JavaScript 基础和面试手写题

    JavaScript 基础和面试手写题 call/bind 的模拟实现 节流/防抖 节流: 当 N 秒内不断触发的...

  • JavaScript - 防抖

    防抖的原理:在n秒后执行触发的事件,如果在n秒内又触发了这个事件,就以新触发事件的事件为准,n秒后再执行该事件。 ...

  • JavaScript防抖

    function debounce(fn,delay){ let delagTime = delag || 500...

  • Javascript 基础

    1、函数防抖和函数节流 【《javascript高级程序设计》里,函数节流是这里讲的函数防抖。】函数防抖: 在事件...

  • JS笔试题

    JavaScript 笔试部分 实现防抖函数(debounce) 防抖函数原理:在事件被触发 n 秒后再执行回调,...

  • 【JavaScript基础】看我如何解释函数防抖与函数节流

    【JavaScript基础】看我如何解释函数防抖与函数节流 博客说明 文章所涉及的资料来自互联网整理和个人总结,意...

  • 分享:22道JavaScript高频手写面试题

    JavaScript笔试部分 实现防抖函数(debounce) 防抖函数原理:在事件被触发n秒后再执行回调,如果在...

  • javaScript 防抖函数

    一. 防抖函数的定义与使用 防抖函数的定义 防抖函数的调用 二. 防抖函数应用场景 其实在HTML 和javaSc...

网友评论

      本文标题:JavaScript基础(四)防抖

      本文链接:https://www.haomeiwen.com/subject/qelkmqtx.html