Angularjs防抖动输入


<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.staticfile.org/angular.js/1.4.6/angular.min.js"></script>
	</head>
	<body ng-controller="myCtrl">
	        <div ng-app="App" ng-controller="Ctrl" class="app">
	            <button ng-click="inc()">Add</button>
	            <span>{{ val }}</span>
	        </div>
	        <script>
	            angular.module("App", []).controller("Ctrl", ['$scope', '$debounce', function($scope, $debounce) {
	                        $scope.shouldBeFocus = true;
	                        $scope.val = 0;
	                        $scope.inc = function() {
	                            $debounce(increase, 300);
	                        };
	
	                        var increase = function() {
	                            $scope.val++;
	                        }
	
	                    }]).factory('$debounce', ['$rootScope', '$browser', '$q', '$exceptionHandler',
	                        function($rootScope, $browser, $q, $exceptionHandler) {
	                            var deferreds = {},
	                                methods = {},
	                                uuid = 0;
	
	                            function debounce(fn, delay, invokeApply) {
	                                var deferred = $q.defer(),
	                                    promise = deferred.promise,
	                                    skipApply = (angular.isDefined(invokeApply) && !invokeApply),
	                                    timeoutId, cleanup,
	                                    methodId, bouncing = false;
	
	                                // check we dont have this method already registered
	                                angular.forEach(methods, function(value, key) {
	                                    if(angular.equals(methods[key].fn, fn)) {
	                                        bouncing = true;
	                                        methodId = key;
	                                    }
	                                });
	
	                                // not bouncing, then register new instance
	                                if(!bouncing) {
	                                    methodId = uuid++;
	                                    methods[methodId] = {
	                                        fn: fn
	                                    };
	                                } else {
	                                    // clear the old timeout
	                                    deferreds[methods[methodId].timeoutId].reject('bounced');
	                                    $browser.defer.cancel(methods[methodId].timeoutId);
	                                }
	
	                                var debounced = function() {
	                                    // actually executing? clean method bank
	                                    delete methods[methodId];
	
	                                    try {
	                                        deferred.resolve(fn());
	                                    } catch(e) {
	                                        deferred.reject(e);
	                                        $exceptionHandler(e);
	                                    }
	
	                                    if(!skipApply) $rootScope.$apply();
	                                };
	
	                                timeoutId = $browser.defer(debounced, delay);
	
	                                // track id with method
	                                methods[methodId].timeoutId = timeoutId;
	
	                                cleanup = function(reason) {
	                                    delete deferreds[promise.$$timeoutId];
	                                };
	
	                                promise.$$timeoutId = timeoutId;
	                                deferreds[timeoutId] = deferred;
	                                promise.then(cleanup, cleanup);
	
	                                return promise;
	                            }
	
	                            // similar to angular's $timeout cancel
	                            debounce.cancel = function(promise) {
	                                if(promise && promise.$$timeoutId in deferreds) {
	                                    deferreds[promise.$$timeoutId].reject('canceled');
	                                    return $browser.defer.cancel(promise.$$timeoutId);
	                                }
	                                return false;
	                            };
	
	                            return debounce;
	                        }
	                    ]);;
	        </script>
	    </body>
</html>


posted @ 2019-09-29 15:39  可爱的黑精灵  阅读(498)  评论(0)    收藏  举报