UNPKG

@progress/kendo-react-grid

Version:
200 lines • 8.11 kB
/** * @hidden */ var VirtualScroll = /** @class */ (function () { function VirtualScroll(cached) { this.containerHeight = 0; this.topCacheCount = 0; // 4; this.attendedSkip = 0; // -4; this.propsSkip = 0; this.total = 0; this.scrollableVirtual = false; this.realSkip = 0; this.pageSize = 0; this.heightContainer = null; this.prevScrollPos = 0; this.tableTranslate = 0; this.scrollSyncing = false; if (cached) { this.topCacheCount = 4; this.attendedSkip = -this.topCacheCount; } this.scrollHandler = this.scrollHandler.bind(this); } Object.defineProperty(VirtualScroll.prototype, "rowHeights", { /** * @return - The row heights in an array. */ get: function () { var result = []; var allRows = this.tableBody && this.tableBody.children || []; var accumulate = 0; for (var i = 0; i < allRows.length; i++) { if (allRows[i].className.indexOf('k-grouping-row') > -1) { accumulate += allRows[i].scrollHeight; continue; } if (allRows[i].className.indexOf('k-detail-row') > -1) { result[result.length - 1].line += allRows[i].scrollHeight; } else { result.push({ line: allRows[i].scrollHeight, acc: accumulate }); accumulate = 0; } } return result; }, enumerable: true, configurable: true }); VirtualScroll.prototype.changePage = function (skip, e) { this.attendedSkip = skip - this.topCacheCount; this.PageChange({ skip: Math.max(0, skip - this.topCacheCount), take: this.pageSize }, e); }; VirtualScroll.prototype.translate = function (dY) { this.tableTranslate = dY; if (this.table) { this.table.style.transform = 'translateY(' + dY + 'px)'; } }; VirtualScroll.prototype.syncScroll = function () { if (!this.scrollableVirtual || !this.container) { return; } this.syncTimeout = null; var scrollTop = this.container.scrollTop; var containerHeight = this.containerHeight; // = this.container.scrollHeight; var rowHeights = this.rowHeights; var percentage = (scrollTop - this.tableTranslate) / rowHeights[0].line; var targetFloorScrollPosition = Math.floor((containerHeight) * (this.propsSkip + percentage) / this.total); if (this.container.scrollTop !== (this.prevScrollPos = targetFloorScrollPosition)) { this.scrollSyncing = true; this.container.scrollTop = (this.prevScrollPos = targetFloorScrollPosition); } this.translate(this.tableTranslate + targetFloorScrollPosition - scrollTop); }; VirtualScroll.prototype.reset = function () { this.scrollSyncing = true; if (this.container) { this.container.scrollTop = 0; } this.translate(0); }; VirtualScroll.prototype.localScrollUp = function (e) { if (!this.container) { return; } var heights = this.rowHeights; var scrollTop = this.container.scrollTop; var targetTranslate = this.tableTranslate; var rowsCount = 0; var additionalOnTop = scrollTop - targetTranslate; if (additionalOnTop > 0) { return; } while ((rowsCount < this.topCacheCount + this.attendedSkip - this.realSkip) && this.propsSkip - rowsCount > 0 && !(targetTranslate + (heights[heights.length - 1 - rowsCount].line + heights[heights.length - 1 - rowsCount].acc) + additionalOnTop <= scrollTop)) { targetTranslate -= heights[heights.length - 1 - rowsCount].line + heights[heights.length - 1 - rowsCount].acc; rowsCount++; } if (rowsCount === 0 && this.topCacheCount === 0 && this.attendedSkip > 0) { // allows local scrolling up, when top caching is disabled // for variable heights 'topCacheCount' should be atleast 1 to avoid flickering targetTranslate = Math.max(targetTranslate - heights[0].line, 0); rowsCount = 1; } if (this.propsSkip - rowsCount <= 0 && targetTranslate > scrollTop) { this.translate(0); this.changePage(0, e); this.container.scrollTop = 0; return; } if (targetTranslate > scrollTop) { targetTranslate = scrollTop; // need to handle these cases // if the item height is not available: // floor the translate to beginning of the item in absolute value } if (targetTranslate !== this.tableTranslate) { this.translate(targetTranslate); this.changePage(this.propsSkip - rowsCount, e); } }; VirtualScroll.prototype.localScrollDown = function (e) { if (!this.container) { return; } var heights = this.rowHeights; var scrollTop = this.container.scrollTop; var targetTranslate = this.tableTranslate; var rowsCount = 0; while (rowsCount < heights.length - this.topCacheCount && !(targetTranslate + heights[rowsCount].line + heights[rowsCount].acc > scrollTop)) { targetTranslate += heights[rowsCount].line + heights[rowsCount].acc; rowsCount++; } if (rowsCount >= heights.length - this.topCacheCount && this.propsSkip + rowsCount >= this.total) { this.translate(targetTranslate); this.changePage(this.total - 1, e); } else if (targetTranslate !== this.tableTranslate) { this.translate(targetTranslate); this.changePage(this.propsSkip + rowsCount, e); } }; VirtualScroll.prototype.scrollNonStrict = function (e) { var floatRowIndex = this.total * this.prevScrollPos / (this.containerHeight); var rowIndex = Math.floor(floatRowIndex); if (rowIndex >= this.total) { rowIndex = this.total - 1; } var rowpercentage = Math.min(floatRowIndex - rowIndex, 1); var microAdjust = 0; var rowIndexOffset = rowIndex - this.propsSkip; var heights = this.rowHeights; if (rowIndexOffset >= 0 && rowIndexOffset <= 1) { microAdjust = -((heights[0].line + heights[0].acc) * rowpercentage); } else if (rowIndexOffset === -1) { microAdjust = -((heights[heights.length - 1].line + heights[heights.length - 1].acc) * rowpercentage); } this.translate(microAdjust + this.containerHeight * floatRowIndex / this.total); this.changePage(rowIndex, e); }; VirtualScroll.prototype.scrollHandler = function (e) { if (!this.scrollableVirtual) { return; } if (this.scrollSyncing || !this.container || !this.table) { this.scrollSyncing = false; return; } var grid = this; clearTimeout(this.syncTimeout); this.syncTimeout = setTimeout(function () { grid.syncScroll(); }, 200); var scrollTop = this.container.scrollTop; var prev = this.prevScrollPos; this.prevScrollPos = scrollTop; if (scrollTop - prev < 0 && scrollTop > this.tableTranslate - this.table.scrollHeight / 10) { this.localScrollUp(e); } else if (scrollTop - prev > 0 && scrollTop < this.tableTranslate + this.table.scrollHeight * 2 / 3) { this.localScrollDown(e); } else { this.scrollNonStrict(e); } this.prevScrollPos = scrollTop; }; return VirtualScroll; }()); export { VirtualScroll }; //# sourceMappingURL=VirtualScroll.js.map