Skip to content

Commit

Permalink
Merge pull request #1651 from Robinson7D/scroll_throttle
Browse files Browse the repository at this point in the history
Add throttle to scroll event
  • Loading branch information
c0bra committed Oct 3, 2014
2 parents 48121e6 + 009d4b8 commit c755753
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 3 deletions.
5 changes: 2 additions & 3 deletions src/js/core/directives/ui-grid.js
Expand Up @@ -103,10 +103,9 @@

/* Event Methods */

//todo: throttle this event?
self.fireScrollingEvent = function(args) {
self.fireScrollingEvent = gridUtil.throttle(function(args) {
$scope.$broadcast(uiGridConstants.events.GRID_SCROLL, args);
};
}, self.grid.options.scrollThrottle, {trailing: true});

self.fireEvent = function(eventName, args) {
// Add the grid to the event arguments if it's not there
Expand Down
3 changes: 3 additions & 0 deletions src/js/core/factories/GridOptions.js
Expand Up @@ -160,6 +160,9 @@ angular.module('ui.grid')
this.excessColumns = 4;
this.horizontalScrollThreshold = 2;

// Default time to throttle scroll events to.
this.scrollThrottle = 70;

/**
* @ngdoc boolean
* @name enableSorting
Expand Down
49 changes: 49 additions & 0 deletions src/js/core/services/ui-grid-util.js
Expand Up @@ -964,6 +964,55 @@ module.service('gridUtil', ['$log', '$window', '$document', '$http', '$templateC
return debounce;
};

/**
* @ngdoc method
* @name throttle
* @methodOf ui.grid.service:GridUtil
*
* @param {function} func function to throttle
* @param {number} wait milliseconds to delay after first trigger
* @param {Object} params to use in throttle.
*
* @returns {function} A function that can be executed as throttled function
*
* @description
* Adapted from debounce function (above)
* Potential keys for Params Object are:
* trailing (bool) - whether to trigger after throttle time ends if called multiple times
* @example
* <pre>
* var throttledFunc = gridUtil.throttle(function(){console.log('throttled');}, 500, {trailing: true});
* throttledFunc(); //=> logs throttled
* throttledFunc(); //=> queues attempt to log throttled for ~500ms (since trailing param is truthy)
* throttledFunc(); //=> updates arguments to keep most-recent request, but does not do anything else.
* </pre>
*/
s.throttle = function(func, wait, options){
options = options || {};
var lastCall = 0, queued = null, context, args;

function runFunc(endDate){
lastCall = +new Date();
func.apply(context, args);
$timeout(function(){ queued = null; }, 0);
}

return function(){
/* jshint validthis:true */
context = this;
args = arguments;
if (queued === null){
var sinceLast = +new Date() - lastCall;
if (sinceLast > wait){
runFunc();
}
else if (options.trailing){
queued = $timeout(runFunc, wait - sinceLast);
}
}
};
};

return s;
}]);

Expand Down
32 changes: 32 additions & 0 deletions test/unit/core/services/ui-grid-util.spec.js
Expand Up @@ -40,6 +40,38 @@ describe('ui.grid.utilService', function() {
}));
});

describe('throttle()', function() {
var x;
var func = function () {
x++;
};

it('prevents multiple function calls', inject(function ($timeout) {
x = 0;

var throttledFunc = gridUtil.throttle(func, 10);
throttledFunc();
throttledFunc();
throttledFunc();
expect(x).toEqual(1);
$timeout.flush();
expect(x).toEqual(1);
}));

it('queues a final event if trailing param is truthy', inject(function ($timeout) {
x = 0;

var throttledFunc = gridUtil.throttle(func, 10, {trailing: true});
throttledFunc();
throttledFunc();
throttledFunc();
expect(x).toEqual(1);
$timeout.flush();
expect(x).toEqual(2);
}));

});

describe('readableColumnName', function() {
it('does not throw with null name', function() {
expect(function() {
Expand Down

0 comments on commit c755753

Please sign in to comment.