函数节流与防抖

函数节流与防抖在操作dom的时候很实用。比如用户在点击提交按钮时,防止用户重复点击导致多次提交一样的数据,为了限制用户重复点击,我们需要采取措施来防止重复提交数据,这就可以用到我们所说的函数防抖,在一定时间类触发同样的事件时,只执行最后一次。最近正好在看underscore.js的源码,看到了节流和防撞的实现,今天抽时间来整理下函数的节流与防抖在实际开发中的应用场景。

1.节流

节流是指函数按照固定的时间来执行一次,比如调用鼠标事件的mousemove时,如果没做任何处理,当鼠标移动的时候,会一直触发mousemove的回调函数,假设使用函数节流,将固定时间设置为200毫秒一次,在这200毫秒内,无论鼠标怎么移动,都不会触发`mousemove``的回调函数,这就是我们所说的节流。

1.1应用场景

主要是应用在一些高频事件,比如mousemovekeyup等。

1.2实现原理

节流的实现原理主要是通过定时器来完成,设定一个时间后,判断定时器是否为空,如果定时器为空就立即执行,定时器不为空时,在定时器设置的时间内不执行回调函数,达到设置的时间后才执行回调函数,具体的实现代码如下所示,代码使用的是underscore.js中节流的代码。

        /*
        * 节流
        * */
        this.throttle = function (func,wait) {
            var timeout, context, args, result;
            var previous = 0;
            var self = this;
            var later = function() {
                previous = self.now();
                timeout = null;
                result = func.apply(context, args);
                if (!timeout) context = args = null;
            };

            var throttled = function() {
                var now = self.now();
                if (!previous) previous = now;
                var remaining = wait - (now - previous);
                context = this;
                args = arguments;
                if (remaining <= 0 || remaining > wait) {
                    if (timeout) {
                        clearTimeout(timeout);
                        timeout = null;
                    }
                    previous = now;
                    result = func.apply(context, args);
                    if (!timeout) context = args = null;
                } else if (!timeout) {
                    timeout = setTimeout(later, remaining);
                }
                return result;
            };

            throttled.cancel = function() {
                clearTimeout(timeout);
                previous = 0;
                timeout = context = args = null;
            };

            return throttled;
        }

2.防抖

当持续触发事件时,在一定时间内没有再次触发时才会执行一次,如果在指定时间内持续触发,每次触发的时候将重新计时。比如给按钮添加点击事件时,用户快速的连续点击按钮,只执行规定时间内最后执行的那一次。

2.1应用场景

主要是应用在一些持续触发事件,比如快速点击,scroll,resize等事件。

2.2实现原理

防抖的实现原理还是借助于定时器,当持续触发函数时,每次将定时器清空重置,重新生成一个定时器,然后再指定的时间后执行回调函数,具体的实现代码如下所示,代码使用的是underscore.js中节流的代码。

      /*
        * 去抖
        * */
        this.debounce = function (func,wait,immediate) {
            var timeout, args, context, timestamp, result,self = this;
            var later = function() {
                var last = self.now() - timestamp;
                if (last < wait && last >= 0) {
                    timeout = setTimeout(later, wait - last);
                } else {
                    timeout = null;
                    if (!immediate) {
                        result = func.apply(context, args);
                        if (!timeout)
                            context = args = null;
                    }
                }
            };

            return function() {
                context = this;
                args = arguments;
                timestamp = self.now();
                var callNow = immediate && !timeout;
                if (!timeout)
                    timeout = setTimeout(later, wait);

                if (callNow) {
                    result = func.apply(context, args);
                    context = args = null;
                }

                return result;
            };
        }

实例

针对mousemove事件和click事件写了一个简单的demo,代码如下:




    
    节流去抖
    


    

个人博客

你可能感兴趣的:(函数节流与防抖)