angular debounce throttle

throttle

我们这里说的throttle就是函数节流的意思。再说的通俗一点就是函数调用的频度控制器,是连续执行时间间隔控制。主要应用的场景比如:

  • 鼠标移动,mousemove 事件
  • DOM 元素动态定位,window对象的resize和scroll 事件

有人形象的把上面说的事件形象的比喻成机关枪的扫射,throttle就是机关枪的扳机,你不放扳机,它就一直扫射。我们开发时用的上面这些事件也是一样,你不松开鼠标,它的事件就一直触发。回到window resize和scroll事件的基本优化提到的优化:

 
 
  1. var resizeTimer=null;
  2. $(window).on('resize',function(){
  3. if(resizeTimer){
  4. clearTimeout(resizeTimer)
  5. }
  6. resizeTimer=setTimeout(function(){
  7. console.log("window resize");
  8. },400);
  9. }
  10. );

setTimeout和clearTimeout其实就是一个简单的 throttle,很多好的控制了resize事件的调用频度。

debounce

debounce和throttle很像,debounce是空闲时间必须大于或等于 一定值的时候,才会执行调用方法。debounce是空闲时间的间隔控制。比如我们做autocomplete,这时需要我们很好的控制输入文字时调用方法时间间隔。一般时第一个输入的字符马上开始调用,根据一定的时间间隔重复调用执行的方法。对于变态的输入,比如按住某一个建不放的时候特别有用。

debounce主要应用的场景比如:

  • 文本输入keydown 事件,keyup 事件,例如做autocomplete

这类网上的方法有很多,比如Underscore.js就对throttle和debounce进行封装


angular 1.3版本之后可以使用 ngModelOptions参数在设置相应的debounce

ngModelOptions Object

options to apply to the current model. Valid keys are:

  • updateOn: string specifying which event should the input be bound to. You can set several events using an space delimited list. There is a special event called default that matches the default events belonging of the control.
  • debounce: integer value which contains the debounce model update value in milliseconds. A value of 0 triggers an immediate update. If an object is supplied instead, you can specify a custom value for each event. For example:ng-model-options="{ updateOn: 'default blur', debounce: { 'default': 500, 'blur': 0 } }"
  • allowInvalid: boolean value which indicates that the model can be set with values that did not validate correctly instead of the default behavior of setting the model to undefined.
  • getterSetter: boolean value which determines whether or not to treat functions bound tongModel as getters/setters.
  • timezone: Defines the timezone to be used to read/write the Date instance in the model for<input type="date"><input type="time">, ... . It understands UTC/GMT and the continental US time zone abbreviations, but for general use, use a time zone offset, for example, '+0430' (4 hours, 30 minutes east of the Greenwich meridian) If not specified, the timezone of the browser will be used.
1.2版本之前的可以自行进行封装:

angular.module('lz.utils.debounce', [])
        .service('$debounce', ['$timeout', function ($timeout) {
            return function (func, wait, immediate, invokeApply) {
                var timeout, args, me, result;

                function debounce() {
                    /* jshint validthis:true */
                    me = this;
                    args = arguments;
                    var later = function () {
                        timeout = null;
                        if (!immediate) {
                            result = func.apply(me, args);
                        }
                    };
                    var callNow = immediate && !timeout;
                    if (timeout) {
                        $timeout.cancel(timeout);
                    }
                    timeout = $timeout(later, wait, invokeApply);
                    if (callNow) {
                        result = func.apply(me, args);
                    }
                    return result;
                }
                debounce.cancel = function () {
                    $timeout.cancel(timeout);
                    timeout = null;
                };
                return debounce;
            };
        }])
    /**
     * usage: <XX lz-debounce="500" immediate="true" ng-model="test"></XX>
     */
        .directive('lzDebounce', ['$debounce', '$parse', function (debounce, $parse) {
            return {
                require: 'ngModel',
                priority: 999,
                link: function ($scope, $element, $attrs, ngModelController) {
                    var debounceDuration = $parse($attrs.debounce)($scope);
                    var immediate = !!$parse($attrs.immediate)($scope);
                    var debouncedValue, pass;
                    var prevRender = ngModelController.$render.bind(ngModelController);
                    var commitSoon = debounce(function (viewValue) {
                        pass = true;
                        ngModelController.$$lastCommittedViewValue = debouncedValue;
                        ngModelController.$setViewValue(viewValue);
                        pass = false;
                    }, parseInt(debounceDuration, 10), immediate);
                    ngModelController.$render = function () {
                        prevRender();
                        commitSoon.cancel();
                        //we must be first parser for this to work properly,
                        //so we have priority 999 so that we unshift into parsers last
                        debouncedValue = this.$viewValue;
                    };
                    ngModelController.$parsers.unshift(function (value) {
                        if (pass) {
                            debouncedValue = value;
                            return value;
                        } else {
                            commitSoon(ngModelController.$viewValue);
                            return debouncedValue;
                        }
                    });
                }
            };
        }]);






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值