Better scrollToRow with requestAnimationFrame

This commit is contained in:
Faris Ansari 2017-12-15 00:36:38 +05:30
parent a4677014da
commit 22782cf7bd
7 changed files with 539 additions and 528 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -100,19 +100,6 @@ export default class CellManager {
return true;
};
const scrollToCell = (direction) => {
if (!this.$focusedCell) return false;
if (!this.inViewport(this.$focusedCell)) {
const { rowIndex } = $.data(this.$focusedCell);
this.scrollToRow(rowIndex - this.getRowCountPerPage() + 2);
return true;
}
return false;
};
['left', 'right', 'up', 'down'].map(
direction => keyboard.on(direction, () => focusCell(direction))
);
@ -122,7 +109,7 @@ export default class CellManager {
);
['left', 'right', 'up', 'down'].map(
direction => keyboard.on(direction, () => scrollToCell(direction))
direction => keyboard.on(direction, () => this.scrollToCell(this.$focusedCell))
);
keyboard.on('esc', () => {
@ -538,46 +525,17 @@ export default class CellManager {
return $.style($('.data-table-row', this.bodyScrollable), 'height');
}
inViewport($cell) {
let colIndex, rowIndex; // eslint-disable-line
if (typeof $cell === 'number') {
[colIndex, rowIndex] = arguments;
} else {
let cell = $.data($cell);
colIndex = cell.colIndex;
rowIndex = cell.rowIndex;
}
const viewportHeight = this.instance.getViewportHeight();
const rowHeight = this.getRowHeight();
const rowOffset = rowIndex * rowHeight;
const scrollTopOffset = this.bodyScrollable.scrollTop;
if (rowOffset - scrollTopOffset + rowHeight < viewportHeight) {
return true;
}
return false;
}
scrollToCell($cell) {
if ($.inViewport($cell, this.bodyScrollable)) return;
const { rowIndex } = $.data($cell);
this.scrollToRow(rowIndex);
this.rowmanager.scrollToRow(rowIndex);
}
getRowCountPerPage() {
return Math.ceil(this.instance.getViewportHeight() / this.getRowHeight());
}
scrollToRow(rowIndex) {
const offset = rowIndex * this.getRowHeight();
this.bodyScrollable.scrollTop = offset;
}
}
export function getCellHTML(column) {

View File

@ -104,6 +104,7 @@ export default class ColumnManager {
let $resizingCell, startWidth, startX;
$.on(this.header, 'mousedown', '.data-table-col .column-resizer', (e, $handle) => {
document.body.classList.add('data-table-resize');
const $cell = $handle.parentNode.parentNode;
$resizingCell = $cell;
const { colIndex } = $.data($resizingCell);
@ -119,6 +120,7 @@ export default class ColumnManager {
});
$.on(document.body, 'mouseup', (e) => {
document.body.classList.remove('data-table-resize');
if (!$resizingCell) return;
isDragging = false;

View File

@ -157,3 +157,23 @@ $.closest = (selector, element) => {
return $.closest(selector, element.parentNode);
};
$.inViewport = (el, parentEl) => {
const { top, left, bottom, right } = el.getBoundingClientRect();
const { top: pTop, left: pLeft, bottom: pBottom, right: pRight } = parentEl.getBoundingClientRect();
return top >= pTop && left >= pLeft && bottom <= pBottom && right <= pRight;
};
$.scrollTop = function scrollTop(element, offset) {
let c = 0;
scroll();
function scroll() {
if (c <= offset) {
c = c + offset / 8;
requestAnimationFrame(scroll);
element.scrollTop = c;
}
}
};

View File

@ -147,6 +147,26 @@ export default class RowManager {
getLastRowIndex() {
return this.datamanager.getRowCount() - 1;
}
scrollToRow(rowIndex) {
const $row = this.getRow$(rowIndex);
if ($.inViewport($row, this.bodyScrollable)) return;
const { top, height } = $row.getBoundingClientRect();
const { top: pTop } = this.bodyScrollable.getBoundingClientRect();
let offset;
if (top < pTop) {
offset = this.bodyScrollable.scrollTop - (pTop - top) - height;
if (offset < 0) offset = 0;
} else {
offset = this.bodyScrollable.scrollTop + (top - this.bodyScrollable.clientHeight);
}
console.log(rowIndex, offset);
$.scrollTop(this.bodyScrollable, offset);
}
}
export function getRowHTML(columns, props) {

View File

@ -234,4 +234,8 @@ button, input {
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
body.data-table-resize {
cursor: col-resize;
}