Skip to content

Commit c755753

Browse files
committed
Merge pull request #1651 from Robinson7D/scroll_throttle
Add throttle to scroll event
2 parents 48121e6 + 009d4b8 commit c755753

File tree

4 files changed

+86
-3
lines changed

4 files changed

+86
-3
lines changed

src/js/core/directives/ui-grid.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,9 @@
103103

104104
/* Event Methods */
105105

106-
//todo: throttle this event?
107-
self.fireScrollingEvent = function(args) {
106+
self.fireScrollingEvent = gridUtil.throttle(function(args) {
108107
$scope.$broadcast(uiGridConstants.events.GRID_SCROLL, args);
109-
};
108+
}, self.grid.options.scrollThrottle, {trailing: true});
110109

111110
self.fireEvent = function(eventName, args) {
112111
// Add the grid to the event arguments if it's not there

src/js/core/factories/GridOptions.js

+3
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ angular.module('ui.grid')
160160
this.excessColumns = 4;
161161
this.horizontalScrollThreshold = 2;
162162

163+
// Default time to throttle scroll events to.
164+
this.scrollThrottle = 70;
165+
163166
/**
164167
* @ngdoc boolean
165168
* @name enableSorting

src/js/core/services/ui-grid-util.js

+49
Original file line numberDiff line numberDiff line change
@@ -964,6 +964,55 @@ module.service('gridUtil', ['$log', '$window', '$document', '$http', '$templateC
964964
return debounce;
965965
};
966966

967+
/**
968+
* @ngdoc method
969+
* @name throttle
970+
* @methodOf ui.grid.service:GridUtil
971+
*
972+
* @param {function} func function to throttle
973+
* @param {number} wait milliseconds to delay after first trigger
974+
* @param {Object} params to use in throttle.
975+
*
976+
* @returns {function} A function that can be executed as throttled function
977+
*
978+
* @description
979+
* Adapted from debounce function (above)
980+
* Potential keys for Params Object are:
981+
* trailing (bool) - whether to trigger after throttle time ends if called multiple times
982+
* @example
983+
* <pre>
984+
* var throttledFunc = gridUtil.throttle(function(){console.log('throttled');}, 500, {trailing: true});
985+
* throttledFunc(); //=> logs throttled
986+
* throttledFunc(); //=> queues attempt to log throttled for ~500ms (since trailing param is truthy)
987+
* throttledFunc(); //=> updates arguments to keep most-recent request, but does not do anything else.
988+
* </pre>
989+
*/
990+
s.throttle = function(func, wait, options){
991+
options = options || {};
992+
var lastCall = 0, queued = null, context, args;
993+
994+
function runFunc(endDate){
995+
lastCall = +new Date();
996+
func.apply(context, args);
997+
$timeout(function(){ queued = null; }, 0);
998+
}
999+
1000+
return function(){
1001+
/* jshint validthis:true */
1002+
context = this;
1003+
args = arguments;
1004+
if (queued === null){
1005+
var sinceLast = +new Date() - lastCall;
1006+
if (sinceLast > wait){
1007+
runFunc();
1008+
}
1009+
else if (options.trailing){
1010+
queued = $timeout(runFunc, wait - sinceLast);
1011+
}
1012+
}
1013+
};
1014+
};
1015+
9671016
return s;
9681017
}]);
9691018

test/unit/core/services/ui-grid-util.spec.js

+32
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,38 @@ describe('ui.grid.utilService', function() {
4040
}));
4141
});
4242

43+
describe('throttle()', function() {
44+
var x;
45+
var func = function () {
46+
x++;
47+
};
48+
49+
it('prevents multiple function calls', inject(function ($timeout) {
50+
x = 0;
51+
52+
var throttledFunc = gridUtil.throttle(func, 10);
53+
throttledFunc();
54+
throttledFunc();
55+
throttledFunc();
56+
expect(x).toEqual(1);
57+
$timeout.flush();
58+
expect(x).toEqual(1);
59+
}));
60+
61+
it('queues a final event if trailing param is truthy', inject(function ($timeout) {
62+
x = 0;
63+
64+
var throttledFunc = gridUtil.throttle(func, 10, {trailing: true});
65+
throttledFunc();
66+
throttledFunc();
67+
throttledFunc();
68+
expect(x).toEqual(1);
69+
$timeout.flush();
70+
expect(x).toEqual(2);
71+
}));
72+
73+
});
74+
4375
describe('readableColumnName', function() {
4476
it('does not throw with null name', function() {
4577
expect(function() {

0 commit comments

Comments
 (0)