diff --git a/src/components/virtualRepeat/virtual-repeater.js b/src/components/virtualRepeat/virtual-repeater.js index c9ea5c8d7f9..68b38db9d17 100644 --- a/src/components/virtualRepeat/virtual-repeater.js +++ b/src/components/virtualRepeat/virtual-repeater.js @@ -346,15 +346,15 @@ VirtualRepeatContainerController.prototype.resetScroll = function() { VirtualRepeatContainerController.prototype.handleScroll_ = function() { var offset = this.isHorizontal() ? this.scroller.scrollLeft : this.scroller.scrollTop; - if (offset === this.scrollOffset) return; + if (offset === this.scrollOffset || offset > this.scrollSize - this.size) return; var itemSize = this.repeater.getItemSize(); if (!itemSize) return; var numItems = Math.max(0, Math.floor(offset / itemSize) - NUM_EXTRA); - var transform = this.isHorizontal() ? 'translateX(' : 'translateY('; - transform += (numItems * itemSize) + 'px)'; + var transform = (this.isHorizontal() ? 'translateX(' : 'translateY(') + + (numItems * itemSize) + 'px)'; this.scrollOffset = offset; this.offsetter.style.webkitTransform = transform; @@ -362,7 +362,7 @@ VirtualRepeatContainerController.prototype.handleScroll_ = function() { if (this.bindTopIndex) { var topIndex = Math.floor(offset / itemSize); - if (topIndex !== this.topIndex && topIndex < this.repeater.itemsLength) { + if (topIndex !== this.topIndex && topIndex < this.repeater.getItemCount()) { this.topIndex = topIndex; this.bindTopIndex.assign(this.$scope, topIndex); if (!this.$rootScope.$$phase) this.$scope.$digest(); @@ -627,6 +627,15 @@ VirtualRepeatController.prototype.getItemSize = function() { }; +/** + * Called by the container. Returns the size of a single repeated item. + * @return {?number} Size of a repeated item. + */ +VirtualRepeatController.prototype.getItemCount = function() { + return this.itemsLength; +}; + + /** * Updates the order and visible offset of repeated blocks in response to scrolling * or items updates. diff --git a/src/components/virtualRepeat/virtual-repeater.spec.js b/src/components/virtualRepeat/virtual-repeater.spec.js index 11562656420..749d97d4522 100644 --- a/src/components/virtualRepeat/virtual-repeater.spec.js +++ b/src/components/virtualRepeat/virtual-repeater.spec.js @@ -616,6 +616,21 @@ describe('', function() { expect(offsetter.children().length).toBe(3); })); + it('should not scroll past the bottom', function() { + scope.items = createItems(101); + createRepeater(); + + scroller[0].scrollTop = ITEM_SIZE * 91; + scroller.triggerHandler('scroll'); + + expect(getTransform(offsetter)).toBe('translateY(880px)'); + + scroller[0].scrollTop++; + scroller.triggerHandler('scroll'); + + expect(getTransform(offsetter)).toBe('translateY(880px)'); + }); + /** * Facade to access transform properly even when jQuery is used; * since jQuery's css function is obtaining the computed style (not wanted)